シスアーキ in はてな

シスアーキ(自称)の技術ブログ

2015 in Action

今年もいよいよあと少し。今年はどんな年だったかな?
振り返ってみたいと思います。

1、2月

情報処理のセキュリティの勉強をしていたように思います。あとはAndroidの勉強。ちょうどお仕事ではAndroidプロジェクトの開発立ち上げで四苦八苦していました。
その後決まったJJUG CCCの資料づくりで、情報処理の勉強は断念したのですがw。来年はきちんと受けないとね。

3月

Spring Bootの勉強会に参加してました。
kanjava.connpass.com
Spring は、お仕事含めてあまり関わりがなかったのですが、Bootをキッカケに気になる存在です。来年はなにか縁があるかな?
その後開かれた懇親会で、JJUG CCCの当選が決まったことを知って、目眩いがしたのを覚えていますw

4月

JJUG CCC 2015 Springで発表しました!
Sessions / JJUG CCC 2015 Spring(4月11日開催) | 日本Javaユーザーグループ


スライドはこちらです!
www.slideshare.net
いや〜、緊張しましたね。人前で話すの苦手なんですよ。
ちなみに、このスライドで紹介したプロジェクトの方式設計リーダー兼プロジェクトサブリーダを努めましたが、無事に成功を納めることが出来ました!今年の仕事「ベスト嬉しかったで賞」は、やはりこのプロジェクトの成功です。色んな人と協力して仕上げる仕事は面白いです!

5月

お仕事忙しくてわたわたしていました。不具合やスケジュールとの戦い。ストレスフルな日々でしたね。

6月

GS Collectionsのハンズオンなどのイベントに参加しました。
kanjava.connpass.com
今はEclipse Collectionsですね。Eclipse Collectionsいいですね!どこかお仕事で使ってみたいです。

7月

Java 8徹底再入門のハンズオンイベントに参加していました。
kanjava.connpass.com
やっぱりハンズオンみたいな参加形式イベントは好きです!来年も積極的に参加したいです。

8月

なにしてたっけ?ww
仕事が落ち着いて、わりと遊んでいた気がします。

9月

DevLOVE関西「現場のアーキテクチャの話をしてみませんか?」でアーキテクチャに関する発表をしました。
devlove-kansai.doorkeeper.jp
スライドはこちらです。

www.slideshare.net
すごいシスアーキに囲まれて緊張しましたw
来年はもう少し立派なシスアーキになれるよう精進したいです。

10月

お別れの月でした。仕事が落ち着いて、去っていくメンバーの送別会しました。
この業界、仕方のないことですが、メンバとの別れはいつも切ないです。

11月

JJUG CCC 2015 Fallに参加しました。
JJUG CCC 2015 Fall(11月28日開催) | 日本Javaユーザーグループ
凄い人達の刺激を受けました。来年も行きたいです!

12月

システムエンジニア Advent Calendar 2015に1日だけ参加させて貰いました!
qiita.com
いやあ、凄い記事ばかりですね。僕もこういう立派なアーキになりたいです。
ちなみに僕は12/20に参加させて頂きました。記事はこちらです!
システム間連携 - 他システムとのデータベース連携について - Qiita

あとはこんな事もしていましたw
朝は意識高く、夜は心を癒して。朝活は来年も続けて行きたいと思います。
www.adventar.org
www.adventar.org

総論

お仕事でビックプロジェクトを成功出来たのは本当によかったです。プロジェクトの成功に密かにコミットしていましたので。
ただ、自分自身としてはいろんなことが中途半端だったと思います。
今年の反省を胸に来年を頑張りたいと思います!

いろんな人に支えられて今年もどうにかやってこれた一年でした。
これからも好きな人、大切な人達と楽しい時間を過ごせますように。。

みなさん、来年もよろしくお願いします!
2015年、バイナリ〜( ´ ▽ ` )ノ

移管完了おめ!Eclipse Collections!!(((o(*゚▽゚*)o)))

この記事は続・AndroidでJavaFXを動かしてみたよ! - シスアーキ in はてなの追記です!
kozake.hatenablog.com
12/24 に Eclipse Collectionsが移管されました!!
クリスマスプレゼントに間に合いましたね!
早速試してみましょう!!

dependenciesをeclipse-collectionsに修正して、

subprojects {
            :
            :
    dependencies {
//        compile 'com.goldmansachs:gs-collections:7.0.0'
        compile 'org.eclipse.collections:eclipse-collections:7.0.0'
    }
}

HelloWorld:androidInstallタスクをターン*1

ビルドエラーぁ。。orz

FAILURE: Build failed with an exception.

What went wrong:
Execution failed for task ':HelloWorld:apkDebug'.
 com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK LICENSE-EDL-1.0.txt
       :
       :

なんか踏んだみたいです。
javafxports / javafxmobile-plugin / issues / #6 - Building a android apk with maven dependencies seams to add them more than once — Bitbucket

packagingOptionsを追加しましょう!

jfxmobile {
    ios {
        forceLinkClasses = [ 'org.javafxports.**.*' ]
    }
    // ここにandroidの環境を定義
    android {
        packagingOptions {
            exclude 'LICENSE-EDL-1.0.txt'
            exclude 'LICENSE-EPL-1.0.txt'
        }
        applicationPackage = 
            "org.javafxports.${project.name.toLowerCase()}"
        androidSdk = '/Applications/adt-bundle-mac-x86/sdk'
    }
}

HelloWorld:androidInstallタスクをぽちっと(恐る恐る

おお!ビルドが成功しました!もちろん、きちんと動きましたよ!!
移管完了おめでとうございます!!(((o(*゚▽゚*)o)))

*1:かっこよくエンターキーを押そうな!

続・AndroidでJavaFXを動かしてみたよ!

JavaFXアドベントカレンダーの23日目です!
qiita.com

みなさ〜ん、今日もJavaFXですか〜!!

JavaFXは僕の好きな技術*1ですが、イマイチ現場で使われている感がありません。その理由はずばり、スマートフォンタブレットなどのモバイル端末への対応の遅れだと感じております。Javaと言ったら「Write once, run anywhere」!やっぱり、モバイル端末上でも動いてほしい!!
去年、
AndroidでJavaFXを動かしてみたよ! - シスアーキ in はてな
という記事でJavaFXアドベントカレンダーに投稿しましたが、今回もその続編で行きたいと思います!

JavaFXPorts とは

JavaFXPorts はGluonでメンテナンスされているOSSです。Gluonといえば、Scene Builderのバイナリを配布してくれていることで有名ですね。JavaFXPortsを用いることで、JavaFXをモバイル端末や組み込みハードウェアで実行させることができます。JavaFXPortsのコンセプトは次の図に一番あらわれています。
f:id:kozake:20151223101709p:plain

使ってみよう!

では、JavaFXPortsを使ってみましょう!JavaFXPortsをAndroidで使う上で必要な環境は次の通りです。

必要環境

Hello World

JavaFXPortsのサンプルが用意されているので、bitbucketからクローンを作成します。

hg clone https://bitbucket.org/javafxports/samples

samplesというプロジェクトが出来ましたね!
Androidの場合はandroid用の定義が必要です。jfxmobileに以下の定義を追加します。androidSdkに、自分の環境のAndroid SDKのパスを定義してください。

jfxmobile {
    ios {
        forceLinkClasses = [ 'org.javafxports.**.*' ]
    }
    // ここにandroidの環境を定義
    android {
        applicationPackage = 
            "org.javafxports.${project.name.toLowerCase()}"
        androidSdk = '/Applications/adt-bundle-mac-x86/sdk'
    }
}

Android端末をUSB接続して*2、クローンしたプロジェクトのディレクトリで以下のコマンドを実行します。

./gradlew HelloWorld:androidInstall

「HelloWorld」というアプリが出来ましたね!起動してみると、
f:id:kozake:20151223111626p:plain
はい、起動できました!!

なにが起きたの?

JavaFXPortsにはJavaFXMobileプラグインが用意されています。そのプラグインを用いることで、AppleのAppStoreやAndroid Play Storeにアップロードできるパッケージが作成できます。JavaFXPortsを動作させるにはJavaFXSDKが必要となるのですが、それもこのプラグインがダウンロードして勝手にインストールしてくれます。androidInstallはJavaFXMobileプラグインが用意するタスクの1つで、その実行のなかでSDKのダウンロードから様々なことをやってくれたんですね*3

Androidでラムダっちゃ♡

では、HelloWorldのソースを見てみましょう!
ソースは、

  • /samples/HelloWorld/src/main/java/org/javafxports/helloworld/Main.java

にあります。

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Rectangle2D visualBounds =
                Screen.getPrimary().getVisualBounds();
        double width = visualBounds.getWidth();
        double height = visualBounds.getHeight();

        Label label = new Label("Click the button.");
        label.setTranslateY(30);

        Button button = new Button("Hello JavaFXPorts");
        button.setOnAction(e ->
                label.setText("You clicked the button!"));

        Rectangle rectangle =
                new Rectangle(width - 20, height - 20);
        rectangle.setFill(Color.LIGHTBLUE);
        rectangle.setArcHeight(6);
        rectangle.setArcWidth(6);

        StackPane stackPane = new StackPane();
        stackPane.getChildren().addAll(
                rectangle, button, label);

        Scene scene = new Scene
                (stackPane,
                visualBounds.getWidth(),
                visualBounds.getHeight());

        stage.setScene(scene);
        stage.show();
    }
}

お気づきいただけたでしょうか...

        button.setOnAction(e ->
                label.setText("You clicked the button!"));

ラムダ!そう、ラムダです。なんとAndroidでラムダが使えている!なんで?Dalvik VMJava SE 7ランタイムみたいなVM*4じゃなかったの!?はい、JavaFXPortsを使うと、ラムダが使えるんですね。なぜかというと、RetroLambdaというツー ルで、ラムダ式が(バイトコード・レベルで)変換できるからなのです。RetroLambdaはクラス・ファイルを調査して、す べ ての invokedynamic呼出しを、Java SE 7で サポートされるinvoke呼出しに置き換えてくれます。

やったぜ、父さん!これでStreamも使い放題だね♡!

Streamを使ってみる。

        button.setOnAction(e ->
                label.setText(Stream.of("Hello", "Lambda")
                        .collect(Collectors.joining(" "))));

と書き換えて、HelloWorld:androidInstallタスクをターン*5!よし、インストールできたぜ!
ボタンをポチっとな!

はい、落ちました。。orz

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/stream/Stream;
at org.javafxports.helloworld.Main.lambda$start$0(Main.java:31)
at org.javafxports.helloworld.Main.access$lambda$0(Main.java)
       :
       :

AndroidおよびiOSJava ランタイム環境は、現時点ではJava 8 固有のAPIをサポートしていません。ですので、Java 8固有のAPIを利用できないのです。これでは、ラムダの実力半減ですね。。

そこでGS Collectionsですよ!

GS Collectionsとは、ゴールドマン・サックスの開発したオープンソースコレクションフレームワークです。GS CollectionsはStream APIも使え、さらに便利な機能を備えています。なんとJava 5からサポートされています!詳しくはこちらをご覧下さい。現在は、Eclipse Collectionsに移管中みたいなので、GS Collectionsを用いてみます!
12/24 に Eclipse Collectionsが移管されました!!(((o(*゚▽゚*)o)))。
詳細はこちら

dependenciesにgs-collectionsを加えて、

subprojects {
            :
            :
    dependencies {
        compile 'com.goldmansachs:gs-collections:7.0.0'
    }
}

GS Collectionsを使った形に修正!

        button.setOnAction(e ->
                label.setText(
                        Lists.immutable.of("Hello", "Lambda")
                            .makeString(" ")));

ボタンをポチっ(恐る恐る

f:id:kozake:20151223124705p:plain

おお!動きましたね!!

javafxmobile-plugin-ensembleを動かす!

また、面白いサンプルとしてはjavafxmobile-plugin-ensembleがあります。こちらを動かしてみましょう!

hg clone https://bitbucket.org/javafxports/javafxmobile-plugin-ensemble

先ほどと同様にjfxmobileのandroidSdkに自分の環境のAndroid SDKのパスを定義してからインストール。

./gradlew androidInstall

f:id:kozake:20151223143648p:plain

おお!EnsembleがAndroidで動いている!!

まとめ

どうだったでしょうか。なかなか去年から比べてよくなっているようにおもいます。
これなら業務にも使えそうですね!え、なに?テキストに日本語が入力できない?バックキーがきかない?そんなの運用でカバーすればいいんですよ*6

*1:出来るとは言ってない

*2:開発者向けオプションでUSBデバッグを有効にしておいてくださいね

*3:すごいよ、Gradle!

*4:言い回しには気を使っております、はい

*5:かっこよくエンターキーを押そうな!

*6:つらい

JJUG CCC 2015 Fallに参加してきました!!(((o(*゚▽゚*)o)))

JJUG CCC 2015 Fallに参加してきました!!

JJUG CCC 2015 Fall(11月28日開催) | 日本Javaユーザーグループ

最高に楽しかったです。やっぱり自分はJavaとそのコミュニティが好きなんだな〜と再認識しました。

keynote-1 基調講演1 : Javaは守りに入らない、これが今のJavaだ

@cero_tさんによる基調講演です。


さすが@cero_t さん、とても会場を湧かす発表でした!本日の発表を一つ一つ魅力的かつ丁寧に紹介してくれました。この時点でどれに参加するか決めかねていた僕は、もう迷いまくりですw。今回は魅力的なセッションが多すぎたと思います。

keynote-2 基調講演2:Java EE 8 – Work in Progress

Java EE 8のお話です。英語セッションでしたが通訳の方が頑張ってくれて、英語が苦手な僕にも優しいセッションでした。JAX-RSでServer Sent Events(SSE)が出来るようになったり、JAX-RSの仕組みでMVCが実装されたりと、最初は仕様が小さかったJAX-RSがどんどん肥大化していくんだな〜という感想です。JAX-RSは僕の好きな技術の一つですが、「出来るだけシンプルであってほしい」という想いと、「色々と出来ることが欲しい」という想いが双方あります。ともあれ、今後の動向に注目です。

お昼

エビスの飲めるお店を発見(((o(*゚▽゚*)o))) !!スタウト美味しかったよ〜*・゜゚・*:.。..。.:*・'(*゚▽゚*)'・*:.。. .。.:*・゜゚・*

GH-1 JAX-RS入門および実践

うらがみさんの発表です。
発表資料はこちら。
JAX-RS入門および実践

JAX-RSの入門と実践の両方について、とてもボリュームのある発表です。今からJAX-RSを仕事で使う方は、かならず目を通しておいたほうがいいかと思います。うらがみさんは大舞台でも落ち着いて話していて、流石だな〜と思いました。個人的には、「JSR 339 - Appendix C Processing Pipeline」の図を交えて説明してくれている部分がとても良かったです。僕がJAX-RSを始めた時にこの資料があったら、もっと早く理解が進んだのにな〜wと思いました。

EF-1エバンジェリスト直伝!Kotlinを既存プロダクトで使う!

たろうさんの発表です。
発表資料はこちら。
エバンジェリスト直伝!Kotlinを既存プロダクトで使う #jjug_ccc #jjug #jkug // Speaker Deck

うらがみさんの資料は事前にレビューに参加させて頂いていたので、途中からたろうさんの発表にも参加しました。今年はAdvent Calendarが速攻で埋まるとか、Kotlinはとても勢いがあります。Android開発ではもう普通に使って問題なさそうですね。Androidのベース言語がこのままJavaのままかどうかという話しも含め、今後の動向に注目です。
Reified type parametersをinline関数と一緒に使う事で、型の情報が保持できるなどの話しが感心しました。

EF-3 Reactive Webアプリケーション – そしてSpring 5へ

@making さんの発表です。
発表資料はこちら。
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3

凄いボリュームですww。正直、この人全部話すつもりないだろうwwって思ってました。時間がない割に、小ネタも挟んでくるしw。しかしながら、とてもスムーズかつ分かりやすい説明で最後まで説明して頂けました。Reactiveについてはまだまだ理解できていないことが多いですが、この発表でだいぶと理解が進んだように思います。さすが、周りより1年早く先を行くmakingさんの発表ですね。

GH-4 GS CollectionsからEclipse Collectionsへ - 機能豊富なオープンソースJavaコレクションフレームワーク

伊藤さんの発表です。
発表資料はこちら。
http://www.goldmansachs.com/gs-collections/documents/2015-11-28_JJUG_CCC.pdf

伊藤さんには以前に関ジャバでもハンズオンを開催していただくなど、お世話になりました!
GS Collections 道場[ハンズオン][OSS コレクションフレームワーク] - connpass
今回は、GS CollectionsがEclipse Collectionsになるということで、もう一度復習したい気持ちがあって参加させて頂きました。


Eclipseという名前に変わっただけで、現場への導入障壁が格段にさがったように思います。機会があれば、業務に導入したいと考えています。Eclipse Collectionsの機能はGS Collections 7.0と同一。「我々としては、Javaの標準に入ってもいいくらい優れたフレームワークだと考えている。Eclipse傘下になることで、標準化への道が開ける、かも。」とありますが、僕もJavaの標準に入ってくれると嬉しいライブラリです。資料の問題がボリュームあったので、家で復習したいと思います。

EF-5 これからのコンピューティングの変化とJava

きしださんの発表です。

コンピュータの今の課題とそれに対するJavaの変化をスムーズに解説して頂けました。「CPUのクロックは頭打ち、でもコア数は今後どんどん増える。今までは黙っていてもコンピュータがどんどん早くなっていったけれど、今後は物理的に限界がある。」という話しから始まり、今までのノイマン型コンピュータとは異なる非ノイマン型コンピュータ技術の説明。そしてJava技術への話しへと、つながりのある話しで理解しやすかったです。僕的には、Java言語からHDLソースが生成されるのが驚愕で面白かったですね。また、Pointクラスの説明もつながりがあって理解しやすかったです。

AB-6 【こっそり始める】Javaプログラマコーディングマイグレーション

やんくさんの発表です。
発表資料はこちら。
【こっそり始める】Javaプログラマコーディングマイグレーション

とてもやんくさんらしい発表でした。開発現場の現状とそれに対するアクション。やんくさんの人柄や経験が素直に資料にでていて共感できる資料だと感じました。古いバージョンのJava知識から抜け出せない現場を改善したい方にとって、とても参考になる発表だったと思います。

GH-6 Java8 Stream APIとApache SparkとAsakusa Frameworkの類似点・相違点

やんくさんの資料も事前にレビューさせて頂いていたので、途中からひしだまさんの発表に参加しました。
発表資料はこちら。
Java8 Stream APIとApache SparkとAsakusa Frameworkの類似点・相違点

動機はもちろん、生ひしだまさんを見たかったにつきます。ひしだまさんは存在したんだ!!(失礼)
Asakusa Frameworkの話しです。僕も最近はバッチ処理は並列処理を前提で設計するので、このようなフレームワークの知識も取り入れないといけないなと感じています。途中参加で話についていけなかったので、家でゆっくり資料を拝見したいと思います。
なお、ひしだまさんへの質問コーナーで拍手喝采がありました。


さすがはひしだまさんです。DQ10のフレンド募集中とのことです。

EF-7 コミュニティディスカッション~みんなもやろうコミュニティ運営~

コミュニティディスカッションです。最近、コミュニティ活動もする僕としても凄く気になる議論です。東京と地方で抱える課題の違いや同じ課題、それに対する取り組みや意見など面白かったです。一番感じたのは、女性はピザはあまり好ましくないとのことです^^;.そうなのか〜(><)。宴会部長としては気をつけます^^;


懇親会

懇親会、色々な人と話せて楽しかったです!
ちょっとLTくらいしたいなと当日にふと思って、新幹線で急遽LT準備をして挑んだのですが、見事にデモが失敗(><)
準備不足ですね^^; どこかでリベンジしたいです。っていうか、LTのレベルがみんな高すぎです。

まとめ

本当に刺激満載の楽しいイベントでした!!
それと共に、まだまだ頑張らないといけないな〜と感じました。よ〜し、おじさんまだまだ若い子には負けないぞ!!!(既に負けている気がするが)。

関西Kotlin勉強会 反省会

さる9/19(土) に関西Kotlin勉強会に行ってきました!

connpass.com
connpass.com

勉強会に懇親会、みんなに会えて楽しかったよ〜〜!!!(((o(*゚▽゚*)o)))

とま〜、それはいいのですが、この勉強会で発表したLT資料について、

「資料の内容が技術的に正しくなく、フェアでもない」

と多方面から注意を受ける事態となりました。(−_−;)

この記事はその資料の検証と反省を目的としたものです。
既に資料は取り下げたのですが、迷惑をおかけした方たちへのお詫びと反省をかねて、問題の資料内容について自分なりに検証したいと思います。

反省資料の内容

問題となった資料の構成は次のとおりです。

Scalaで拡張関数を実装したけど、implicitばかりでつらいよね
・Kotlinの拡張関数は簡単にかけるよ!

ここでの問題は、

Scala でFunctorのコードを書いているが間違っている(技術的に正しくない)
Scalaのコードが型クラスを実現しようとしているのに対して、Kotlinのコードはそれを実現しようとしていない(フェアじゃない)

が指摘された内容だと考えています。

Scala でFunctorのコードを書いているが間違っている

まずこれについて。

trait MyFunctor[F[_]] { self =>

  def myMap[A, B](fa: F[A])(f: A => B): F[B]
}
final class MyFunctorOps[F[_],A](val self: F[A])(implicit val F: MyFunctor[F]) {

  def myMap[B](f: A => B): F[B] = F.myMap(self)(f)
}

上記コードについては問題ないと思います。問題は次のコード。

// BAD Logic!!!
implicit val listMyFunctor = new MyFunctor[List] {
  override def myMap[A, B](fa: List[A])(f: (A) => B): List[B] = {
    def myMapFunc(acc: List[B])(l: List[A])(f: A => B): List[B] = {
      l match {
        case (head :: tail) => myMapFunc(acc :+ f(head))(tail)(f)
        case _ => acc
      }
    }
    myMapFunc(Nil)(fa)(f)
  }
}

mapの実装を不必要にややこしく書いています。

// BAD Logic!!!
implicit def listMyFunctor[A](l: List[A]):MyFunctorOps[List, A] =
  new MyFunctorOps[List, A](l)

暗黙の型変換を目的としたロジックが不適切です。
このロジックだと、Functorを実装した分だけ同じような定義をしないといけないです。

とりあえず、まーまー、正しいかと思われるコードについて書きました。
まだ自信ないですが。。

implicit val listMyFunctor = new MyFunctor[List] {
  override def myMap[A, B](fa: List[A])(f: A => B): List[B] = fa.map(f)
}

まず、myMapの実装を簡単に書きました。実装内容は今回の資料の対象ではないので。

  implicit def toMyFunctorOps[F[_], A](fa: F[A])(implicit F: MyFunctor[F]) =
    new MyFunctorOps[F, A](fa)

次に、暗黙の型変換を目的としたロジックを修正しました。
MyFunctorの実装を型ごとに暗黙の引数で受け取れるように修正したことで、同じ定義を書く必要がなくなりました。

Scalaのコードが型クラスを実装しようとしているのに対して、Kotlinのコードはそれを実現しようとしていない

先ほどのFunctorは型クラスを実現しようとしていました。
型クラスはアドホック多相 を実現するものです。
アドホック多相とは、

異なる型の間で共通したインターフェースでの異なる振る舞いを定義済みの型に対して拡張する

ものらしいです。
それを実現する為に、

・型クラスの定義
インスタンスの定義
・型クラスの利用

という手順を踏む必要があります。

今回拡張するFunctorについて、Functorは型パラメータをもつ型です。
先ほどのコードでは、型クラスの定義でFunctor値の型をHigher-kind Genericsを用いて定義し、インスタンスの定義、および型クラスの利用の為にimplicit parameterとimplicit conversionの機能を用いています。

資料の中で「implicitだらけでScala怖い」と表現した件について、僕の現状のScala力では読みにくいという感想でした。ただ、その比較としてKotlinの拡張関数で以下のコードを提示し、Kotlinが簡単と表現したのはフェアじゃないですね。

fun <T, R> List<T>.myMap(f: (T) -> R): List<R> = this.map(f)

上記コードだと、

定義済みの型に対して拡張する

は実現できても、

異なる型の間で共通したインターフェースでの異なる振る舞い

は実現できていないです。上のようなコードだけで良ければ、Scalaのimplicit conversionでも簡単に実現できます。*1

implicit class ToFunctorList[A](l: List[A]) {
  def myMap[B](f: A => B) = l.map(f)
}

ちなみにですが、Kotlinの拡張関数はただのシンタックスシュガーです。

fun <T, R> myMap(l: List<T>, f: (T) -> R): List<R> = l.map(f)

のような関数定義があり、第一引数の型をレシーバとして呼び出せる簡易構文を提供しているみたいです。
実際に、上の定義を同じパッケージ内で定義すると、コンパイラJVM上では同じシグネチャだよって怒られます。

KotlinでFunctorを定義してみる

はい、ではフェアである為にKotlinでFunctorの定義を頑張ってみます。
ただ、KotlinにはHigher-kind Genericsもimplicitのような機能もありません。ですので、違う方法で

異なる型の間で共通したインターフェースでの異なる振る舞いを定義済みの型に対して拡張する

を実現できるよう考えてみました。

・インタフェースの定義
・Delegation機能を用いたインタフェース実装の定義
・拡張関数を用いてインタフェース実装への型変換

interface MyFunctor<A> {

    fun myMap<B>(f: (A) -> B): MyFunctor<B>
}
class MyFunctorList<A>(val list: List<A>) : MyFunctor<A>, List<A> by list {

    override fun myMap<B>(f: (A) -> B): MyFunctor<B>
        = MyFunctorList(list.map(f))

    override fun toString() = list.toString()
}

fun <A> List<A>.asFunctor(): MyFunctorList<A>
    = MyFunctorList(this)
fun main(args: Array<String>) {

    println(arrayListOf(1, 2, 3, 4, 5).asFunctor().myMap { n -> n * 3 })
}

以上です。
KotlinではClass Delegation*2の機能がありますので、拡張する型がインタフェースであれば、委譲クラスを簡単に作成できます*3
Scalaのように強力ではないですが、

異なる型の間で共通したインターフェースでの異なる振る舞いを定義済みの型に対して拡張する

は実現できたのではないかと思います。

今回の反省

LTはライトニングトークであって、軽いノリで誤った資料でいい訳ではない

ってことですね。
深夜のテンションで酒飲みながら資料作るのはもうやめようっと。。

修正版の資料はこちらにアップしました!

www.slideshare.net
また、上記コードは以下にアップしています。
kozake/ScalaStudyFunctor · GitHub
kozake/KotlinStudyFunctor · GitHub

<09/23 追記>
上記Kotlinコードにおいても、Scalaで実現していることを実現出来ていないと指摘を受けました。
確かに実現できていないので、比較対象としては不適切です。あくまで参考レベルの記事とさせてください。

*1:まあ、資料の中でもあくまでネタで、Scalaでも簡単に実現できるとは書いていましたが。。

*2:Delegationhttp://kotlinlang.org/docs/reference/delegation.html

*3:残念なことにクラスの委譲クラスは作成できないですが

Java 8徹底再入門(大阪,7/11)に参加しました!!

Java 8徹底再入門(大阪,7/11)に参加しました。

1. 栄養補充

勉強会前の栄養補給。

美味しかったです!(((o(*゚▽゚*)o)))
既にこの時点でやりきった感。( ๑°ω°๑)و グッ!
#じゃないだろ

2. 【Date and Time API

@khasunuma さんによる「Date and Time API」の発表です。
「Date and Time API」はJava8から導入された新しい日付APIですが、そのAPIの複雑さ(実際は日付の概念そのものが複雑だから仕方ないのだが)や、従来のjava.util.Dateとの違い・相互運用などで戸惑っている方も多いと思います。
これらについて、そもそもの時間の概念や「Date and Time API」の基本理念から丁寧に説明頂けました。

その時の詳細やスライドはこちらのブログ纏められておりますので、興味のある方はご参照ください。

「Java 8徹底再入門」に登壇しました。 - Programming Studio

また、「Date and Time API」についてのツイートがこちらに纏められています*1

Date and Time APIを理解する為には、ISO 8601に踏み込みましょう! - Togetterまとめ

「Date and Time API」についての纏めとしては、

  • Date and Time API は ISO 8601 (コンピュータ間でデータのやりとりをする際の、日付と時刻の書式に関する国際規格)モデリングして作られたものということを意識すること(ただし、ZonedDateTimeはそれとは違うということも意識すること)
  • まずはLocalDateについてマスターすること
  • Local/Offset/Zoned の存在意義を把握すること
  • 色々試してみること!

とのことでした!。やっぱり色々試してみるのが大事ですね!

個人的な感想としては、

  • 時間には人間の歴史や国ごとの政治があるということを感じた。
  • 1秒の基準となっているのは、セシウム(Cs133)の共鳴周波数で、これを利用したものが原子時計という話が面白かった。*2
  • 「ZonedDateTime」使用する場合は、内部のtz databaseの運用を考えないといけない、ミッションクリティカルシステムでJavaVMのバージョンアップなどを運用フェーズで行えるかどうかの考慮などが必要、という話にハッとした。
  • 個人的には、JDBCやORMの対応状況が気になる。

というところです。まだまだ現場での使用実績に乏しいAPIだと思いますが、今後の主流になると思いますので、それに備えたいと思います。

3. 【ラムダ式ハンズオン】

@bitter_fox さんによる「ラムダ式ハンズオン」です。@bitter_fox さんは学生さんですが、Lambdaにも若干絡んでいる最年少JDKコミッタです。
Paraya(GlassFish ディストリビューション)のContributorの@khasunuma さんのセッションといい、どう考えても今回は豪華イベントです。

ハンズオンの内容は次のようなものでした。

  • ラムダ式の書き方
  • FunctionalInterfaceの定義方法
  • forEachを用いた繰り返し処理の書き方
  • Streamの説明。Streamの生成・中間操作・終端操作
  • mapの使い方
  • 乱数を返す無限Streamを用いてのreduceやsummaryStatisticsの使い方
  • Optionalの説明
  • ParallelStreamの説明と実験
  • Streamを使ったファイルからの読み込み
  • CollectorとCollectorsの説明
  • flatMapの説明
  • Collectorsの使い方(toList/joining/groupingBy)
  • groupingByConcurrentの説明

ハンズオンは@bitter_fox さんの説明と、スクリーン上のコードを写経する形で淡々と進んでいきました。滑らかで分かりやすい説明で難しさは感じなかったかもしれませんが、これだけの説明が行われていたのですね!本当、凄い事ですよ。

個人的な感想としては、

  • OptionalにgetAsDouble()を使ってましたヽ(;▽;)ノ!すいません、負け組です。
  • Files.linesで生成したStreamのクローズ漏れが発覚ヽ(;▽;)ノ!
  • Collectorの並列処理の順序について自分の勘違いが発覚ヽ(;▽;)ノ!

大丈夫か?俺

 ハンズオンの説明の上手さに感心しました。reduceの説明とかは難しいだろうなと思っていましたが、とても分かりやすい図とともに説明していて、流石だと感心しました。

一方で、やっぱりflatMapの説明には苦労されていた模様です。時間もなかったし、ここは難しいですね。

最後のほうでgroupingByConcurrentについて説明頂けたのが嬉しかったです。凄い興味深い内容でした。

本当、説明・進行が上手だったのと、参加者のスキルが高かったので、TA業が暇でした。ハンズオンの内容とは関係ないのですが、前回のGSCollectionsのハンズオンも含めて、ハンズオン形式での進め方(教え方)について凄い勉強になりました。自分が教える立場になった時の参考になりそうです。

4. 【懇親会】

串カツ食べ放題・飲み放題で飲みまくりました!(((o(*゚▽゚*)o)))


その後は二次会にも参加、最後はGeekBearが4周年イベントやっていたので、ちょっとだけ顔出したらビール奢ってもらいました!

ありがとうございます、楽しかったです!!!
*・゜゚・*:.。..。.:*・'(*゚▽゚*)'・*:.。. .。.:*・゜゚・*

*1:そもそもこのツイートが今回の勉強会に繋がったのです

*2:10万年に1秒程度の誤差しか生まないというのは凄いですね!