Scala勉強会@関東#2でLiftについて発表してきたんだぜ?
はい、というわけで。
Scala-ja - Scala勉強会@関東-2でLiftについて発表してきましたよ。
Scala勉強会@関東-2 終了 - Scalaとか構文解析についてあれこれ書く日記
発表資料はこちら。
まず、発表する段階でPCセットアップしようとして、VGAアダプタを忘れてくるという醜態をさらす。
結局、発表順を入れ替えてもらってSofmapに買いに走るというダメっぷりをキメた!!
あと、Wiiリモコンでプレゼンをやってみよう!と思ったが、当日はWiiリモコンを認識してくれなくてあきらめた。
発表の方も、Mavanコマンドに失敗したりでうまくいかないところが多かった。
時間も足りなくて最後までやれなかったし。
反省点は多いぞ。
まぁいろいろダメだったけど、発表してよかった。
で、作る予定だったLiftで実装したTropyクローンは、Githubにあげておきます。
興味のある人は触ってみたり、もっとScala的に書き直したりしてみてくれると幸せになれます(オレが)。
liftropy/target at master · yuroyoro/liftropy · GitHub
全体的な感想。
- 何となくアカデミックな雰囲気(場所が東大の研究室だったから?)
- Haskellとかの前提知識が不足してた。もっと勉強が必要だオレは。
- Hands onみたいに、みんなでコード書いてみよう的なイベントがあるとおもしろいかも?
- 内容的にかなり濃い感じ。だがそれがいい。
- 懇親会でのアツさ。ってかC++0x?
参加された皆さん、お疲れ様でした!
Memo
■Scalaチュートリアル 2.7.2 scalaのGenericがjavaから見えるようになった Javaとの相互依存したプログラムがコンパイル可能 if else → elseを核と値を返す ?みたいな 書かない場合はUnit型の値が帰る forでコレクション要素について繰り返し forで配列やリストなどを生成できる for(x <- 1 to 50;y <- 1 to 50 if y == x * x ) yield( x,y) 実はmap,flatpap,filterのメソッド呼び出しへのsyntax sugar whileはforよりも冗長だけど高速 高階関数 foldLeft 関数を引数にとる関数 def open(path:String)(block:InputStream => Unit){ var in =new FileInputStream(path) try{block(in)}finally{in.close} } 引数なしメソッドの呼び出しで()は諸略できる クラス定義 クラス名に続けてコンストラクタ引数を定義 valをつけると外部から読み取り可能 引数のスコープはクラス定義全体 演算子は通常のメソッドとして定義 def thisを定義するとコンストラクタをOverloadする trait インスタンス生成できない。多重継承。ようはMixin。RubyのModuleなど。 object - Singletonを作る。クラスと同様superclassを指定できる。 implicit conversion 暗黙の型変換 implicit def int2Dtring( i :Int):String =i.toString Int型に存在しないメソッドの呼び出しを検出 →Stringへの暗黙の変換をコンパイルが試みる 危険な変換を定義しないようにするのは自己責任( String2Intなど) class RangeExt( range:Range){ def exclude(elem :Int )=range.filter(e => e!= elem) } implicit def range2RangeExt( f :Range) :RangeExt = new RangeExt(r) 既存のクラスにメソッドを追加するなどで使われる パターンマッチング 式 match { case パターン => ....} switch分をより強力に パターンにマッチした値を変数に束縛可能 構造を持つデータをパターンマッチに使える collectionなど case Array Case Class -パターンマッチに使える MLとかのalgebraic datatype Extractor 既存の型に新しいパターンを定義する機能 unapplyメソッドで動作を定義する Structural type 静的に型チェックされるduck typing 特定のシグニチャのメソッドをもっているかのみがチェックされる def printName(x:{def name():String}) =println(x.name) Lazy value 部分的な遅延評価 lazy val x =println("x") 一度評価された値は再計算されない Partial function 引数から値を計算できるを isDefinedAtによって関数を実行することなく得られる Actorライブラリ等で活用 lazy val fib :PartialFunction[iInt:Int] ={ case 0 |1 =>1 case パターンだけを評価できる XMLリテラル XMLの構造に対するパターンマッチング XMLノードの走査が楽に list match{ case <ul>{items@_*}</ul> =>item.foreach Generics val x:Array{String] = Array("A","B","C") クラス名の後に[型パラメータ] 型パラメータは普通の型で扱える implicit parameter 引数にimplicitを付加 呼び出し側のスコープでimplicitな値が定義されていれば明示的に渡さなくても良い implicit object ScalaCheckでよく使われる Existential type Array[String]はArray[AnyRef]のサブタイプではない Array[T} forSom {type T} 任意の型の配列のスーパータイプ 書き込み不可 ■ASN.1ライブラリをScalaでDSL風に(tmiyaさん) 肝心な本編が聞けなかったorz ライブラリの作り方 各*.scalaファイルをobject Foobli{}で囲む 使うコード側でImport Enumの作り方 scalaのEnumはなんか使いにくい 自分でobject作った方がいい Patternマッチ便利すぐる value objectはcase classにしておく Option[T]は便利 何もない場合nullではんく Some(t)とNoneで場合分け HaskellのMaybe monad.どこかで implicit conversionは便利 既存クラスにメソッドを追加したい場合 ■Parser Combinator yaccやJavaCC scala.uti.parsing.combinator 基本的なパッケージ scala.uti.parsing.combinator.lexical 字句解析 scala.uti.parsing.combinator.syntacical 便利に使うためのパッケージ ()の対応をチェックするパーザ Parsar[T] 基本クラス Parsarを組み合わせる extends (Reader) => Parsers.ParseResult[T] ストリームを受け取り解析結果を返す関数 Reader[T] :T型のストリーム 副作用はなし 一種の無限リスト Parsers.ParseResult[T] success[T](result : T, next :Reader) Parsers{type Elem} このクラスを継承し、サブクラスで文法を定義する Elem : 入力列 elem(e:Elem) eにマッチするかを検査するパーザを生成 implicit conversionによてElem → Parser[Elem]の変換が定義されてるので通常使わない p ~ q パーザを連結 p | q パーザの順序付き選択 まず最初にpがマッチするか試し,pが失敗した場合のみバックトラックしてqを試す。 p ||| q 順序なし選択。両方マッチし、より長い文字列にマッチした方が解析結果となる p * pの0回以上の繰り返し p ^^ f pが成功したときに関数fを実行 p:Parser[T] f:T=>V p ^^ f ::Parser[V] StanderdTokenParsersがよろしくやってくれる 入力をTokenとして扱ってくれる 空白の読み飛ばし 予約語 JSONパーザ Lexer( scala.util.parsing.json.Lexer) ■ScalaCheck 自動UnitTestツール propertyによる振る舞いの定義 テストデータの自動生成 失敗するケースの最小値の探索 sbazを使ってインストール 2.7.2 finalではバイナリはどうさせず svnからソース落としてant jar property((a:A1,b:A2,...) =>booleanである型が満たす性質を記述する prop#checkでテストする Property テスト可能な基本単位 orc.scalacheck.Propのインスタンス 生成する型の判定 - implicit parameter 基本的な型のみ たとえば自分で作ったクラスとかはimplicit objectであらかじめ宣言しておく