Coding in Style                J. Suereth        Senior Software Engineer粋なコード
Agenda  ● The Scala mindset  ● Scala 2.10 new features  ● A brave new ventureScala 風に考える/Scala 2.10 の新機能/その先へ
Favor Expressions文より式
def isAwesome(data: Data): Boolean = {  if(data.awesome) return true  if(data.lame) return false  return data.contains("Ta...
def isAwesome(data: Data): Boolean =  if(data.awesome) true  else if(data.lame) false  else (data contains "Tasty Sandwich...
def isAwesome(data: Data): Boolean =   (data.awesome ||   (!data.lame) ||   (data contains "Tasty Sandwich"))
Embrace Operator Notation演算子(中置)記法を取り入れよう
def privs(user: Option[User]): Privileges =  user.map(findUserPrivileges).getOrElse(    NoPrivs)
def privs(user: Option[User]): Privileges =  (user map findUserPrivileges   getOrElse NoPrivs)
Let the language do the              work            SUDO Make me a variable作業を言語に任せる
def slurp(file : File): String = {    var input: InputStream = null    var output: OutputStream = null    var read = 0    ...
def slurp(in: File): String = {  val in = new FileInputStream(in)  val out = new StringWriter()  val buf = new Array[Byte]...
Tail-recursioN! @tailrec def read(): Unit =   (in read buf) match {      case 0 => ()      case n =>        out.write(buf,...
Tail-recursioN! @tailrec def read(): Unit =   (in read buf) match { Base Case      case 0 => ()      case n =>        out....
Tail-recursioN! @tailrec def read(): Unit =   (in read buf) match {      case 0 => ()      Recursive Case      case n =>  ...
If it seems useful, look for it便利そうであれば、まずは探そう
def countEm(counts: Seq[Int]): Int = {  var total = 0  for(count <- counts) total += count  total}
def countEm(counts: Seq[Int]): Int =  counts.sum
Collections! ● Scala collections have > 100 useful methods ● By far the biggest reason to use Scala is   manipulating data...
Aim Higher          higher-order-functions, that is上を狙おう (高階関数)
def sort[T](   data: Seq[T])(   lessThan: (T,T) => Boolean): Seq[T] = ...
Why higher order functions? def sort[T](    data: Seq[T] )(    lessThan: (T,T) => Boolean ): Seq[T] = ...     Abstract the...
New w/ Scala 2.10           Features that alter your daily codeScala 2.10 の新機能
Build strings the nice way            interpolators文字列生成を楽に
val   HAI = "HI"val   name = "SQUARE"val   height = 100val   width = 20scala> val x = s"${HAI}"x: String = HIscala> f"$nam...
Keep the abstract....              .... well abstract.抽象的なものは抽象的に
A Graph Library APItrait   Node[N] {     trait Graph[N,E] {  def   value: N        type Nd = Node[N]}                     ...
A Graph Library API trait   Node[N] {     trait Graph[N,E] {   def   value: N        type Nd = Node[N] }         Great for...
Add behavior     with shiny new value classes and implicit classes値クラスとimplicit クラスで振る舞いを追加する
object Graph {  implicit class Ops[N,E](val g: Graph[N,E])      extends AnyVal {    def isAcyclic: Boolean =      cycles f...
object Graph {  implicit class Ops[N,E](val g: Graph[N,E])      extends AnyVal {    def isAcyclic: Boolean =      cycles f...
Fast at runtime, too val graph: Graph[N, E] = ... if(graph.isCyclic) sys.error("O NOES")                  Translates to st...
Cheat in an Emergency             With Dynamic Typesいざという時の動的型
class MapHelper(json: Map[String,AnyRef])    extends Dynamic {  def selectDynamic(name: String) =    (json get name     ge...
scala> val m = new MapHelper(Map[String,AnyRef]("name" -> "Jimmy", "age" -> "10"))m: MapHelper = MapHelper@683f67e0scala> ...
Promise the Future!                Make sure to deliverPromise とFuture (約束は守りましょう)
import scala.concurrent._import scala.concurrent.ExecutionContext.Implicits.globalscala> val x = promise[Int]scala> val y ...
Why not Java Futures?future {                executor.submit(  Thread sleep 30000L  5                     new}            ...
Why not Java Futures?val x: Future[Int] =        val x: Future[Integer] ...                        =                      ...
Why not Java Futures?val x: Future[Int] =   N/A ...val y: Future[Int] = x map { result =>     result + 5                  ...
Scalas Futures Provide a lightweight model for asynchronous, non-blocking execution that can be chained and joined through...
Staying Async!          See http://jsuereth.com/intro-to-fp/いつも非同期で
trait AsynchService {  def users: Future[Seq[User]]  def projects(user: User):Future[Seq[Project]]}
def allprojects(api: AsynchService): Future[Set[Project]] =  (Future.traverse(api.users)(api.projects)   map (_.flatten.to...
Traverse is fork join  def traverse[A](     seq: Future[Seq[A]]    )(     op: A => Future[B]    ): Future[Seq[B]] = ....tr...
Feeling Crazy?            Manipulate some ASTsちょっと遊ぶ?AST をいじろう
object MacroAsserts {    def assert(cond: Boolean, expr: String) =       macro assertImpl    def assertImpl(c: Context)(  ...
object MacroAsserts {                            What the user sees    def assert(cond: Boolean, expr: String) =       mac...
object MacroAsserts {    def assert(cond: Boolean, expr: String) =       macro assertImpl    def assertImpl(c: Context)(  ...
Tree Transformation object Bar {    assert(false,     "THIS IS A BAD OBJECT") }構文木の変換
object Bar {      Expr[Boolean]}                     Expr[Any]
object Bar {                                  Macro      Expr[Boolean]}                     Expr[Any]
object Bar {      Expr[Unit]   Macro}
object Bar {   ()}
A Brave New World                Welcome toすばらしい新世界へようこそ
Whats coming in Scala 2.11?  Nothing certain, but a list of possibilities  ● Smaller     ○ Modularization of components?  ...
ResourcesCollections: http://docs.scala-lang.org/overviews/collections/introduction.htmlString Interpolation: http://docs....
Questions?質問ある?
Coding in Style
Upcoming SlideShare
Loading in...5
×

Coding in Style

984

Published on

Scala Conference in Japan 2013

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
984
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
25
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Coding in Style

  1. 1. Coding in Style J. Suereth Senior Software Engineer粋なコード
  2. 2. Agenda ● The Scala mindset ● Scala 2.10 new features ● A brave new ventureScala 風に考える/Scala 2.10 の新機能/その先へ
  3. 3. Favor Expressions文より式
  4. 4. def isAwesome(data: Data): Boolean = { if(data.awesome) return true if(data.lame) return false return data.contains("Tasty Sandwich")}
  5. 5. def isAwesome(data: Data): Boolean = if(data.awesome) true else if(data.lame) false else (data contains "Tasty Sandwich")}
  6. 6. def isAwesome(data: Data): Boolean = (data.awesome || (!data.lame) || (data contains "Tasty Sandwich"))
  7. 7. Embrace Operator Notation演算子(中置)記法を取り入れよう
  8. 8. def privs(user: Option[User]): Privileges = user.map(findUserPrivileges).getOrElse( NoPrivs)
  9. 9. def privs(user: Option[User]): Privileges = (user map findUserPrivileges getOrElse NoPrivs)
  10. 10. Let the language do the work SUDO Make me a variable作業を言語に任せる
  11. 11. def slurp(file : File): String = { var input: InputStream = null var output: OutputStream = null var read = 0 try { input = new FileInputStream(file) output = new StringOutputStream() val buf = new Array[Byte](BUF_SIZE) read = input.read(buf) while(read > 0) { output.write(buf, 0, read) read = input.read(buf) } } finally { if(input != null) input.close() if(output != null) output.close() } if(output != null) return output.toString return null}
  12. 12. def slurp(in: File): String = { val in = new FileInputStream(in) val out = new StringWriter() val buf = new Array[Byte](BUF_SIZE) def read(): Unit = (in read buf) match { case 0 => () case n => out.write(buf, 0, n) read() } try read() finally in.close() out.toString}
  13. 13. Tail-recursioN! @tailrec def read(): Unit = (in read buf) match { case 0 => () case n => out.write(buf, 0, n) read() }
  14. 14. Tail-recursioN! @tailrec def read(): Unit = (in read buf) match { Base Case case 0 => () case n => out.write(buf, 0, n) read() }
  15. 15. Tail-recursioN! @tailrec def read(): Unit = (in read buf) match { case 0 => () Recursive Case case n => out.write(buf, 0, n) read() }
  16. 16. If it seems useful, look for it便利そうであれば、まずは探そう
  17. 17. def countEm(counts: Seq[Int]): Int = { var total = 0 for(count <- counts) total += count total}
  18. 18. def countEm(counts: Seq[Int]): Int = counts.sum
  19. 19. Collections! ● Scala collections have > 100 useful methods ● By far the biggest reason to use Scala is manipulating data using collectionsScala を使う最大の理由: コレクションを使ったデータ処理
  20. 20. Aim Higher higher-order-functions, that is上を狙おう (高階関数)
  21. 21. def sort[T]( data: Seq[T])( lessThan: (T,T) => Boolean): Seq[T] = ...
  22. 22. Why higher order functions? def sort[T]( data: Seq[T] )( lessThan: (T,T) => Boolean ): Seq[T] = ... Abstract the algorithm (how to do something) from the goal (what to do)目的(何がしたいか) とアルゴリズム(どうやるか) を分離する
  23. 23. New w/ Scala 2.10 Features that alter your daily codeScala 2.10 の新機能
  24. 24. Build strings the nice way interpolators文字列生成を楽に
  25. 25. val HAI = "HI"val name = "SQUARE"val height = 100val width = 20scala> val x = s"${HAI}"x: String = HIscala> f"$name is $height%04d meters by$width%04d meters"res0: String = SQUARE is 0100 meters by 0020meters
  26. 26. Keep the abstract.... .... well abstract.抽象的なものは抽象的に
  27. 27. A Graph Library APItrait Node[N] { trait Graph[N,E] { def value: N type Nd = Node[N]} type Ed = Edge[N,E]trait Edge[N,E] { def value: E def nodes: Set[Nd] def from: Node[N] def edges(n: Nd): Seq[Ed] def to: Node[N] }}
  28. 28. A Graph Library API trait Node[N] { trait Graph[N,E] { def value: N type Nd = Node[N] } Great for implementers, type Ed = Edge[N,E] trait but wheres all the Edge[N,E] { def friendly user methods? Set[Nd] value: E def nodes: def from: Node[N] def edges(n: Nd): Seq[Ed] def to: Node[N] } }実装する人にはいいけど、trait を使う人にやさしくない
  29. 29. Add behavior with shiny new value classes and implicit classes値クラスとimplicit クラスで振る舞いを追加する
  30. 30. object Graph { implicit class Ops[N,E](val g: Graph[N,E]) extends AnyVal { def isAcyclic: Boolean = cycles forall (c => (c drop 1).isEmpty) def cycles: Set[Set[Node[N]]] = ... compute using tarjan or other algorithm ... }}
  31. 31. object Graph { implicit class Ops[N,E](val g: Graph[N,E]) extends AnyVal { def isAcyclic: Boolean = cycles forall (c => (c drop 1).isEmpty) def cycles: Set[Set[Node[N]]] = ... compute using tarjan or other algorithm ... }}
  32. 32. Fast at runtime, too val graph: Graph[N, E] = ... if(graph.isCyclic) sys.error("O NOES") Translates to static helper method call val graph: Graph[N, E] = ... if(Graph.Ops.isCyclic(graph)) sys.error("O NOES")実行時には static メソッドの呼び出しへと変換される
  33. 33. Cheat in an Emergency With Dynamic Typesいざという時の動的型
  34. 34. class MapHelper(json: Map[String,AnyRef]) extends Dynamic { def selectDynamic(name: String) = (json get name getOrElse sys.error(s"Attribute $namenot found in json: $json"))}
  35. 35. scala> val m = new MapHelper(Map[String,AnyRef]("name" -> "Jimmy", "age" -> "10"))m: MapHelper = MapHelper@683f67e0scala> m.nameres1: AnyRef = Jimmyscala> m.sexjava.lang.RuntimeException: Attribute sexnot found in json: Map(name -> Jimmy, age ->10)
  36. 36. Promise the Future! Make sure to deliverPromise とFuture (約束は守りましょう)
  37. 37. import scala.concurrent._import scala.concurrent.ExecutionContext.Implicits.globalscala> val x = promise[Int]scala> val y = x.futurescala> y.isCompletedres5: Boolean = falsescala> x success 5scala> y.isCompletedres7: Boolean = truescala> y.valueres9: Option[Either[Throwable,Int]] = Some(Right(5))
  38. 38. Why not Java Futures?future { executor.submit( Thread sleep 30000L 5 new} Callable<Integer>( ) { def call(): Creating! Integer = { Thread sleep 3000L new Integer(5) }
  39. 39. Why not Java Futures?val x: Future[Int] = val x: Future[Integer] ... = ...Await.result(x, 10 seconds) x.get(10, Blo TimeUnit.SECONDS) cki ng !
  40. 40. Why not Java Futures?val x: Future[Int] = N/A ...val y: Future[Int] = x map { result => result + 5 king } l oc -B ! on ins N a ch
  41. 41. Scalas Futures Provide a lightweight model for asynchronous, non-blocking execution that can be chained and joined throughout your application.Future: 軽量な非同期・ノンブロッキング実行モデル
  42. 42. Staying Async! See http://jsuereth.com/intro-to-fp/いつも非同期で
  43. 43. trait AsynchService { def users: Future[Seq[User]] def projects(user: User):Future[Seq[Project]]}
  44. 44. def allprojects(api: AsynchService): Future[Set[Project]] = (Future.traverse(api.users)(api.projects) map (_.flatten.toSet))
  45. 45. Traverse is fork join def traverse[A]( seq: Future[Seq[A]] )( op: A => Future[B] ): Future[Seq[B]] = ....traverse は fork/join を用いて行われる
  46. 46. Feeling Crazy? Manipulate some ASTsちょっと遊ぶ?AST をいじろう
  47. 47. object MacroAsserts { def assert(cond: Boolean, expr: String) = macro assertImpl def assertImpl(c: Context)( cond: c.Expr[Boolean], msg: c.Expr[String] ): c.Expr[Unit] = if(sys.env("SCALA_ASSERT") == "true") c.reify(if(cond.splice) sys.error(msg.splice)) else c.reify(())}
  48. 48. object MacroAsserts { What the user sees def assert(cond: Boolean, expr: String) = macro assertImpl def assertImpl(c: Context)( cond: c.Expr[Boolean], msg: c.Expr[String] ): c.Expr[Unit] = if(sys.env("SCALA_ASSERT") == "true") c.reify(if(cond.splice) sys.error(msg.splice)) else c.reify(())}
  49. 49. object MacroAsserts { def assert(cond: Boolean, expr: String) = macro assertImpl def assertImpl(c: Context)( cond: c.Expr[Boolean], msg: c.Expr[String] ): c.Expr[Unit] = if(sys.env("SCALA_ASSERT") == "true") c.reify(if(cond.splice) sys.error(msg.splice)) else c.reify(())} What the compiler uses
  50. 50. Tree Transformation object Bar { assert(false, "THIS IS A BAD OBJECT") }構文木の変換
  51. 51. object Bar { Expr[Boolean]} Expr[Any]
  52. 52. object Bar { Macro Expr[Boolean]} Expr[Any]
  53. 53. object Bar { Expr[Unit] Macro}
  54. 54. object Bar { ()}
  55. 55. A Brave New World Welcome toすばらしい新世界へようこそ
  56. 56. Whats coming in Scala 2.11? Nothing certain, but a list of possibilities ● Smaller ○ Modularization of components? ○ Eviction of deprecated libraries? ● Faster ○ More reliable inlining? ○ Method-Handle based closures? ● Stabler ○ Fix ALL THE BUGS ○ Reflection API Stabilizes?より小さく、高速で、安定した Scala 2.11
  57. 57. ResourcesCollections: http://docs.scala-lang.org/overviews/collections/introduction.htmlString Interpolation: http://docs.scala-lang.org/overviews/core/string-interpolation.htmlValue Classes: http://docs.scala-lang.org/overviews/core/value-classes.htmlFutures: http://docs.scala-lang.org/overviews/core/futures.htmlReflection: http://docs.scala-lang.org/overviews/reflection/overview.htmlMacros: http://docs.scala-lang.org/overviews/macros/overview.html
  58. 58. Questions?質問ある?
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×