scalaを触ってみた

31
SCALA 触ってみた SCALA

Upload: nemoto-yusuke

Post on 17-Jul-2015

351 views

Category:

Technology


1 download

TRANSCRIPT

SCALA触ってみたSCALA

http://www.scala-lang.org/

http://www.scala-lang.org/

http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014/?utm_source=hootsuite&utm_campaign=hootsuite

SCALA触ってみた感想

TOC

• 作ったもの

• 使ったもの

• 使いたかったもの

• まとめ

ARCHITECT 作ったもの

ARCHITECT 作ったもの

• SVN内のEclipseプロジェクト依存関係可視化

• 指定URL配下を再帰的に探索

• .classpathファイル内に書かれた依存関係を解析

• Graphvizが食べられるDotファイルを出力

ARCHITECT 作ったもの

ARCHITECT 作ったもの

• https://github.com/kaakaa/DotDispClasspath

UTILITY 使ったもの

LIST 使ったもの

• ScalaのListは基本的には不変(scala.collection.immutableパッケージ)

var list = List.empty[Int]

list = 1 :: list

list = list :+ 1新しいリストを生成する

(先頭追加)

(末尾追加)

(初期化)

Javaのような参照渡しによる変更を気にしなくて良い

PATTERN MATCH 使ったもの

• 柔軟なswitch文

instanceList foreach { _ match { case ClassA => println(“This is ClassA”) case ClassB if _.hasChild() => println(“This is ClassB having ching”) case _ => println(“other class”) } }

(foreach要素を受ける)(クラスでマッチング)(さらに if で条件付き)

(デフォルト)

SYNTAX SUGAR 使ったもの

• 外部コマンド実行Process(“svn list —recursive” + url) !!

• Systemプロパティ取得sys.props(“line.separator”)

• 複数戻り値 (tuple)def method(): (String, Int) = { ~ } (val str, val i) = method()

SYNTAX SUGAR 使ったもの

• 文字列 -> XMLval nodes:NodeSeq = XML loadString str

• XMLタグ取得xml \ “tagName”

• XML要素取得xml \ “@attrName”

nodes foreach { _ match { case ~ } }

CLASSES 使ったもの

OBJECT 使ったもの

• シングルトンなクラス (Scalaにstaticはない)

object ProjectModelCreator { def apply(rootUrl: String) = { var projects = List.empty[Project] for (url <- SvnCommander.recursiveList(rootUrl)) { projects = new Project(url) :: projects } projects } } !ProjectModelCreator(“http://localhost/svn”) <= ( ~ ) はapplyメソッドの呼出し

COMPANION OBJECT 使ったもの

• クラスに従属するobject

class SampleA private (name: String) !object SampleA { def apply(name: String) = { new SampleA(name) } }

=> staticメソッドをまとめる…?

PACKAGE OBJECT 使ったもの

• package内から参照できるobject

package org.kaakaa.classpath.ide !import scala.xml.Node !package object entry { def getPath(entry: Node): String = { entry \ "@path" text } }

org.kaakaa.classpath.ide .entry.ClasspathEntry

参照可能

INTERESTING FEATURE 使いたかったもの

•Implicit Keyword •Parallel Collection •Currying

IMPLICIT KEYWORD 使いたかったもの

val str:String = 10 <= エラー

implicit def intToString(num: Int): String = { num.toString }val str:String = 10 <= 成功

• 型チェックでエラーとなる式について、式の正当性を満たす型変換を実施するimplicitメソッドが、スコープ内で唯一つのとき成功する

PARALLEL COLLECTION 使いたかったもの

scala> def exec(num: Int) = { | Thread.sleep(1000) | println("num = " + num) | } exec: (num: Int)Unit !scala> def measure = { | val start = System.currentTimeMillis() | for(i <- List(1,2,3,4,5)){ exec(i) } | println((System.currentTimeMillis() - start) + "[ms]") | } measure: Unit

scala> measure num = 1 num = 2 num = 3 num = 4 num = 5 5008[ms]

• 普通に実行

PARALLEL COLLECTION 使いたかったもの

scala> def exec(num: Int) = { | Thread.sleep(1000) | println("num = " + num) | } exec: (num: Int)Unit !scala> def parallelMeasure = { | val start = System.currentTimeMillis() | for(i <- List(1,2,3,4,5).par){ exec(i) } | println((System.currentTimeMillis() - start) + "[ms]") | } measure: Unit

scala> parallelMeasure num = 1 num = 4 num = 2 num = 3 num = 5 2022[ms]

• 並列実行

scala> scala.collection.parallel.availableProcessors res2: Int = 4

PARALLEL COLLECTION 使いたかったもの

scala> def exec2(num: Int) = { | println("num = " + num + “ start”) | Thread.sleep(num * 1000) | println("num = " + num + “ end”) | } exec: (num: Int)Unit !scala> def measure2 = { | val start = System.currentTimeMillis() | for(i <- List(1,2,3,4,5).par){ exec2(i) } | println((System.currentTimeMillis() - start) + "[ms]") | } measure: Unit

scala> parallelMeasure3 num = 1 start num = 3 start num = 2 start num = 4 start num = 1 end num = 2 end num = 5 start num = 3 end num = 4 end num = 5 end 7005[ms]

• ?

常にコアの数だけ並行処理できるわけではない

CURRYING 使いたかったもの

• カリー化とは、複数のパラメータをとる関数を、 1つのパラメータをとる関数のチェーンに変換する

f: x × y -> z

g: x -> y -> z

f をカリー化した関数 g

f(x,y) = x + y = z

g(x) = h(y) = x + y = zg(2) = h(y) = 2 + y = z

例)

CURRYING 使いたかったもの

• カリー化と似ている(?)部分適用

def sum(a: Int, b: Int, c: Int): Int = { a + b + c }

def sumPart = sum(_:Int, 2, 3) 引数の内2つを 事前に適用

sumPart(1) => 6

http://togetter.com/li/183700=>カリー化と部分適用の違いと誤用

CURRYING 使いたかったもの

• カリー化(curried)

scala> def sum(a:Int, b:Int, c:Int):Int = { a + b + c } sum: (a: Int, b: Int, c: Int)Int !scala> val g = sum _ g: (Int, Int, Int) => Int = <function3> !scala> val c = g.curried c: Int => (Int => (Int => Int)) = <function1> !scala> c(1)(2)(3) res0: Int = 6

関数オブジェクト取得

関数定義

カリー化

カリー化関数の使用

CONCLUSION まとめ

CONCLUSION まとめ

• Better Java

• とりあえずCollectionとclass周りを固めていきたい

• ScalaではPattern Matchが肝な気がした

• IDEはIntelliJ IDEA使いました

• Eclipseショートカットに設定すればそこまでアレルギー無い

• 英語UIが慣れないけど…

CONCLUSION まとめ

• Scalaで面白そうなもの

• Gitbucket

• Webフレームワーク

• Play / Scalatra / Skinny / Lift …

• Scala.js