Experience report 2009 - 2013Scala en proyectos devinculación ANCAP-URGermán FerrariMarzo 2013@gerferrauy.linkedin.com/in/...
Proyectos2009 - 2010"Modelo estocásticomúltiple-etapa para apoyoa la toma de decisionesen la planificación de laproducción...
EquipoIng. Quim. Bernardo Zimberg - ANCAPM.Sc. Carlos Testuri - FIng, URIng. Comp. Germán Ferrari - FIng, UR
ComponentesModelo matemáticoEscrito en MathprogResuelto con herramientas de GLPKAplicación de escritorioInicialmente: Entr...
Por qué Scala?Único programando, fascinado con el lenguajeJava era una alternativa viableScala es "sólo una biblioteca"
Por qué Scala?Tipado estáticoFavoreceinmutabilidadCódigo legible y cortoInferencia de tiposSin boilerplateDSL friendlyBibl...
Herramientas y bibliotecas usadasScala-Swingspray-jsonScala IOScalaTestscala.sys.processPackratParserssbt, sbt-assembly, s...
Scala-SwingWrapper sobre SwingSe integra naturalmente en ScalaFeel declarativoAPI más simpleUsando MVP inspirado en el pro...
Scala-Swing - ejemplosobject HelloWorld extends SimpleSwingApplication {def top = new MainFrame {title = "Hello, World!"co...
Scala-Swing - ejemplosval b = new Button {text = "OK"font = fpreferredSize = (20, 20)}listenTo(b)reactions += {case Button...
Scala-Swing - ejemplosnew FlowPanel {contents ++= new Button("a") :: new Button("b") :: Nil}new BoxPanel(Horizontal) {cont...
Scala-Swing - a tener en cuentaNo es wrapper 100% completoNo está mantenido activamenteRelativamente fácil de extenderScal...
(De)Serialización de JSON basado en Type-classestrait JsonReader[T] { def read(json: JsValue): T }trait JsonWriter[T] { de...
spray-json - ejemploscase class Color(name: String, red: Int, green: Int,blue: Int)object MyJsonProtocol extends DefaultJs...
spray-json - ejemplosobject JSON extends DefaultJsonProtocol {implicit object PathJsonFormat extends RootJsonFormat[Path] ...
spray-json - ejemplostype RetRels = Seq[(Ship, Ship)]implicit val RetRelsWriter = new RootJsonWriter[RetRels] {def write(r...
spray-json - resumenLógica de conversión desacopladaGran control sobre la conversiónMúltiples implementacionesDistintos ni...
Scala IOEntrada / salida en ScalaManejo simple, portable, correcto y eficiente dearchivos y otros recursos de E/SComponent...
Scala IO - ejemplosimport scalax.file.Pathval path = Path("file")path.byteArray // lee todos los bytes en memoria// `bytes...
Scala IO - ejemplosdef save[T: JsonFormat](t: T, path: Path) {path.write(t.toJson.prettyPrint)(Codec.UTF8)}def load[T: Jso...
Scala IO - ejemplosdef command: (String, URL) = {val name = if (isWin) "cmd.exe" else "cmd"name -> this.getClass.getResour...
Scala IO - ejemplosimport scalax.io._val output:Output = Resource.fromOutputStream(new java.io.FileOutputStream("daily-sca...
ScalaTestFramework de testingMultiples estilos de testTDD - FunSuiteBDD - FunSpecFeatureSpec
ScalaTest - ejemplosimport org.junit.runner.RunWithimport org.scalatest.junit.JUnitRunner@RunWith(classOf[JUnitRunner])cla...
scala.sys.processAPI para ejecutar y controlar procesosIndicar qué correr y cómoManejar E/SCorrer procesoUtilizado para ej...
scala.sys.process - ejemplosimport scala.sys.process._// Ejecuta "ls" y envía la salida a stdout"ls".!// Ejecuta "ls" y de...
scala.sys.process - ejemplosnew URL("http://databinder.net/dispatch/About") #>"grep JSON" #>>new File("About_JSON") !
scala.sys.process - ejemplosval builder = Process(glpsol.cmd,Seq("--model", modelPath.path,"--data", dataPath.path,"--chec...
PackratParsersConstrucción de parsers dentro del lenguajeAdmiten gramaticas recursivas por la izquierdaLos parsers comunes...
PackratParsers - ejemplosexpr ::= term { "+" term | "-" term }term ::= factor { "*" factor | "/" factor }factor ::= floati...
PackratParsers - ejemplossealed trait Exprcase class Add(t1: Expr, t2: Expr) extends Exprcase class Sub(t1: Expr, t2: Expr...
PackratParsers - ejemplosclass Arith extends JavaTokenParsers with PackratParsers {lazy val expr: PackratParser[Expr] =ter...
PackratParsers - ejemploslazy val factor: PackratParser[Expr] = (floatingPointNumber ^^ { str => Num(str.toFloat) }| "(" ~...
PackratParsers - ejemploslazy val term: PackratParser[Expr] =factor ~ rep("*" ~ factor | "/" ~ factor) ^^ {case factor ~ l...
PackratParsers - ejemplosdef parse(str: String): Expr = {val parser = new Arithimport parser._parser.parse(phrase(expr), s...
Otros - importar proyectostype Loader = Path => Option[Project]object Sega1_0_0Loader extends Loader { ... }object Sega2_0...
Otros - importar proyectosdef fromPath(path: Path): Option[Project] =loaders.flatMap { load => load(path) }.headOption
Otros - importar proyectosdef fromPath(path: Path): Option[Project] =loaders.view.flatMap { load => load(path) }.headOption
Otros - importar proyectosdef fromPath(path: Path): Future[Option[Project]] =future {loaders.view.flatMap { load => load(p...
Otros - importar proyectosdef fromPath(path: Path): Future[Option[Project]] =future {loaders.view.flatMap { load => load(p...
sbtname := "sega"version := "2.0.0-SNAPSHOT"scalaVersion := "2.10.1"libraryDependencies <+= scalaVersion( "org.scala-lang"...
sbt - pluginsaddSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2")addSbtPlugin("com.eed3si9n" % "sbt-ass...
sbteclipseEclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE16)EclipseKeys.withSource := trueEcli...
sbt-assemblyimport AssemblyKeys._assemblySettings// ... buil.sbt mostrado antes ...mainClass in assembly := Some("uy.edu.f...
Scala IDE for EclipsePlugin para desarrollo con Scala en EclipseUpdate site Eclipse Indigo y Scala 2.10http://download.sca...
Lo peorEl compilador es lentoLas herramientas de desarrollo consumenmucha memoria
Lo mejorSe puede empezar "pequeño" y crecer ademandaScala es escalable => nuestras aplicacionesson escalablesSe puede tene...
ReferenciasScala generalhttp://docs.scala-lang.org/overviews/Scala-Swinghttp://www.scala-lang.org/sid/8http://ingomaier.bl...
ReferenciasReactive programminghttps://github.com/ingoem/scala-reacthttps://github.com/nafg/reactive/tree/master/reactive-...
ReferenciasScala IOhttp://jesseeichar.github.com/scala-io-doc/http://daily-scala.blogspot.com/2012/07/scala-io-getting-sta...
Referenciasscala.sys.processhttp://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#sca...
Referenciassbthttp://www.scala-sbt.org/https://github.com/paulp/sbt-extrashttps://github.com/sbt/sbt-assemblyhttps://githu...
:)Muchas gracias
Upcoming SlideShare
Loading in...5
×

Scala en proyectos de vinculación Ancap-UR - 2013-03

128

Published on

Diapositivas de una presentación que di para la Scala Meetup Montevideo el 21 de marzo de 2013, para compartir la experiencia de uso de Scala como parte de mi trabajo en proyectos de vinculación entre ANCAP y la Universidad de la República.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
128
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Scala en proyectos de vinculación Ancap-UR - 2013-03

  1. 1. Experience report 2009 - 2013Scala en proyectos devinculación ANCAP-URGermán FerrariMarzo 2013@gerferrauy.linkedin.com/in/gerferra/
  2. 2. Proyectos2009 - 2010"Modelo estocásticomúltiple-etapa para apoyoa la toma de decisionesen la planificación de laproducción"2012 - 2013Extensión al proyectooriginal. En curso
  3. 3. EquipoIng. Quim. Bernardo Zimberg - ANCAPM.Sc. Carlos Testuri - FIng, URIng. Comp. Germán Ferrari - FIng, UR
  4. 4. ComponentesModelo matemáticoEscrito en MathprogResuelto con herramientas de GLPKAplicación de escritorioInicialmente: Entrada de datosCon el tiempoEjecución y monitoreo del solverReporte de resultadosScala
  5. 5. Por qué Scala?Único programando, fascinado con el lenguajeJava era una alternativa viableScala es "sólo una biblioteca"
  6. 6. Por qué Scala?Tipado estáticoFavoreceinmutabilidadCódigo legible y cortoInferencia de tiposSin boilerplateDSL friendlyBiblioteca estándarColeccionesProcesosParsersREPLComunidadFácil! para programadores Java ;)
  7. 7. Herramientas y bibliotecas usadasScala-Swingspray-jsonScala IOScalaTestscala.sys.processPackratParserssbt, sbt-assembly, sbteclipseScala IDE for Eclipse
  8. 8. Scala-SwingWrapper sobre SwingSe integra naturalmente en ScalaFeel declarativoAPI más simpleUsando MVP inspirado en el propuesto enGWTNo muy Scala-like pero funciona
  9. 9. Scala-Swing - ejemplosobject HelloWorld extends SimpleSwingApplication {def top = new MainFrame {title = "Hello, World!"contents = new Button {text = "Click Me!"}}}
  10. 10. Scala-Swing - ejemplosval b = new Button {text = "OK"font = fpreferredSize = (20, 20)}listenTo(b)reactions += {case ButtonClicked(`b`) => //reaction here}
  11. 11. Scala-Swing - ejemplosnew FlowPanel {contents ++= new Button("a") :: new Button("b") :: Nil}new BoxPanel(Horizontal) {contents ++= new Label("text") :: HStrut(2) ::new Button("a") :: HGlue :: new Button("b") :: Nil}new BorderPanel {layout(new Button("North")) = Position.Northlayout(new Button("Center")) = Position.Center}
  12. 12. Scala-Swing - a tener en cuentaNo es wrapper 100% completoNo está mantenido activamenteRelativamente fácil de extenderScalaSwingContribBastante fácil de usar pero falta documentación(Java)Swing usa reflection para algunas cosasScalaFX
  13. 13. (De)Serialización de JSON basado en Type-classestrait JsonReader[T] { def read(json: JsValue): T }trait JsonWriter[T] { def write(obj: T): JsValue }trait JsonFormat[T] extendsJsonReader[T] with JsonWriter[T]Usado para persistir configuración y archivosde proyectosspray-json
  14. 14. spray-json - ejemploscase class Color(name: String, red: Int, green: Int,blue: Int)object MyJsonProtocol extends DefaultJsonProtocol {implicit val colorFormat: JsonFormat[Color] =jsonFormat4(Color)}import MyJsonProtocol.colorFormatval json = Color("CadetBlue", 95, 158, 160).toJsonval color = json.convertTo[Color]
  15. 15. spray-json - ejemplosobject JSON extends DefaultJsonProtocol {implicit object PathJsonFormat extends RootJsonFormat[Path] {def write(c: Path): JsValue = c.path.toJsondef read(value: JsValue): Path = value.convertTo[String] // string2path}implicit val AppCfgFormat = jsonFormat(AppCfg, "paths", "selPath")}case class AppCfg(paths: Set[Path], selPath: Option[Path])
  16. 16. spray-json - ejemplostype RetRels = Seq[(Ship, Ship)]implicit val RetRelsWriter = new RootJsonWriter[RetRels] {def write(rels: RetRels) =rels.map { case (s1, s2) => s1.name -> s2.name }.toJson}implicit val RetRelsReader = new RootJsonReader[Seq[Ship] => RetRels] {def read(value: JsValue) = { imps =>val ship = imps.map { s => s.name -> s }.toMapvalue.convertTo[Seq[(String, String)]] map {case (n1, n2) => ship(n1) -> ship(n2)}}}val retRels = json.convertTo[Seq[Ship] => RetRels].apply(imps)
  17. 17. spray-json - resumenLógica de conversión desacopladaGran control sobre la conversiónMúltiples implementacionesDistintos niveles de refinamientoConversiones asimétricasEscalableAgregar nuevas conversiones es baratoLas conversiones se pueden combinar
  18. 18. Scala IOEntrada / salida en ScalaManejo simple, portable, correcto y eficiente dearchivos y otros recursos de E/SComponentesIO BásicoArchivosAcceso asincrónicoProcessor
  19. 19. Scala IO - ejemplosimport scalax.file.Pathval path = Path("file")path.byteArray // lee todos los bytes en memoria// `bytes` es lazy y no lee los bytes hasta que son// requeridos o forzadospath.bytes.drop(5).take(5).force// lee todos los bytes en un String. El Codec puede ser// implícitopath.string(Codec.UTF8)
  20. 20. Scala IO - ejemplosdef save[T: JsonFormat](t: T, path: Path) {path.write(t.toJson.prettyPrint)(Codec.UTF8)}def load[T: JsonFormat](path: Path): T = {path.string(Codec.UTF8).asJson.convertTo[T]}
  21. 21. Scala IO - ejemplosdef command: (String, URL) = {val name = if (isWin) "cmd.exe" else "cmd"name -> this.getClass.getResource(name)}val basePath: Path = ...val (cmdName, cmdResource) = commandval cmdPath = basePath / "cmd" / cmdNameResource.fromURL(cmdResource).copyDataTo(cmdPath)cmdPath.attributes = Seq(ExecuteAccessAttribute(true))
  22. 22. Scala IO - ejemplosimport scalax.io._val output:Output = Resource.fromOutputStream(new java.io.FileOutputStream("daily-scala.out"))val in:Input = Resource.fromFile("daily-scala.out")for{processor <- output.outputProcessorout = processor.asOutput}{// todas las escrituras van a ir al mismo output stream/channel abiertoout.write("first writen")out.write("second write")}// muestra las líneas escritasin.string
  23. 23. ScalaTestFramework de testingMultiples estilos de testTDD - FunSuiteBDD - FunSpecFeatureSpec
  24. 24. ScalaTest - ejemplosimport org.junit.runner.RunWithimport org.scalatest.junit.JUnitRunner@RunWith(classOf[JUnitRunner])class DummyTest extends FlatSpec with ShouldMatchers {"A Stack" should "pop values in last-in-first-out order" in {val stack = new Stack[Int]stack.push(1)stack.push(2)stack.pop() should equal (2)stack.pop() should equal (1)}it should "throw NoSuchElementException if an empty stack is popped" in {val emptyStack = new Stack[String]evaluating { emptyStack.pop() } should produce [NoSuchElementException]}}
  25. 25. scala.sys.processAPI para ejecutar y controlar procesosIndicar qué correr y cómoManejar E/SCorrer procesoUtilizado para ejecución y monitoreo del solver
  26. 26. scala.sys.process - ejemplosimport scala.sys.process._// Ejecuta "ls" y envía la salida a stdout"ls".!// Ejecuta "ls" y devuelve `Stream[String]` con la salida.val contents = Process("ls").lines// Ejecuta "ls" y devuelve un String con la salida.def contentsOf(dir: String): String = Seq("ls", dir).!!
  27. 27. scala.sys.process - ejemplosnew URL("http://databinder.net/dispatch/About") #>"grep JSON" #>>new File("About_JSON") !
  28. 28. scala.sys.process - ejemplosval builder = Process(glpsol.cmd,Seq("--model", modelPath.path,"--data", dataPath.path,"--check"))val logger = ProcessLogger { line =>onEDT { view.append(line) }}val proc = builder.run(logger)
  29. 29. PackratParsersConstrucción de parsers dentro del lenguajeAdmiten gramaticas recursivas por la izquierdaLos parsers comunes entran en loopExperimentos muy básicos de parsearentidades Mathprog
  30. 30. PackratParsers - ejemplosexpr ::= term { "+" term | "-" term }term ::= factor { "*" factor | "/" factor }factor ::= floatingPointNumber | "(" expr ")".import scala.util.parsing.combinator._class Arith extends JavaTokenParsers with PackratParsers {lazy val expr: PackratParser[Any] = term ~ rep("+" ~ term | "-" ~ term)lazy val term: PackratParser[Any] = factor ~ rep("*" ~ factor | "/" ~ factor)lazy val factor: PackratParser[Any] = floatingPointNumber | "(" ~ expr ~ ")"}
  31. 31. PackratParsers - ejemplossealed trait Exprcase class Add(t1: Expr, t2: Expr) extends Exprcase class Sub(t1: Expr, t2: Expr) extends Exprsealed trait Term extends Exprcase class Mul(f1: Expr, f2: Expr) extends Termcase class Div(f1: Expr, f2: Expr) extends Termsealed trait Factor extends Termcase class Num(n: Float) extends Factor
  32. 32. PackratParsers - ejemplosclass Arith extends JavaTokenParsers with PackratParsers {lazy val expr: PackratParser[Expr] =term ~ rep("+" ~ term | "-" ~ term) ^^ {case term ~ list => ???}lazy val term: PackratParser[Expr] =factor ~ rep("*" ~ factor | "/" ~ factor) ^^ {case factor ~ list => ???}lazy val factor: PackratParser[Expr] = (floatingPointNumber ^^ { ??? }| "(" ~ expr ~ ")" ^^ { ??? } )}
  33. 33. PackratParsers - ejemploslazy val factor: PackratParser[Expr] = (floatingPointNumber ^^ { str => Num(str.toFloat) }| "(" ~> expr <~ ")")
  34. 34. PackratParsers - ejemploslazy val term: PackratParser[Expr] =factor ~ rep("*" ~ factor | "/" ~ factor) ^^ {case factor ~ list =>@tailrecdef parseFactor(e1: Expr, rest: List[String ~ Expr]): Expr = rest match {case Nil => e1case "*" ~ e2 :: rest1 => parseFactor(Mul(e1, e2), rest1)case "/" ~ e2 :: rest1 => parseFactor(Div(e1, e2), rest1)}parseFactor(factor, list)}
  35. 35. PackratParsers - ejemplosdef parse(str: String): Expr = {val parser = new Arithimport parser._parser.parse(phrase(expr), str) match {case Success(result, _) => resultcase failure: NoSuccess => sys.error(failure.toString)}}parse("2 + 2 * 3 / (5 + 8)")// Add(Num(2.0),Div(Mul(Num(2.0),Num(3.0)),Add(Num(5.0),Num(8.0))))parse("2 + 2 * 3 / 5 + 8")// Add(Add(Num(2.0),Div(Mul(Num(2.0),Num(3.0)),Num(5.0))),Num(8.0))parse("2") // Num(2.0)
  36. 36. Otros - importar proyectostype Loader = Path => Option[Project]object Sega1_0_0Loader extends Loader { ... }object Sega2_0_0Loader extends Loader { ... }val loaders =Sega2_0_0Loader :: Sega1_0_0Loader :: Nil
  37. 37. Otros - importar proyectosdef fromPath(path: Path): Option[Project] =loaders.flatMap { load => load(path) }.headOption
  38. 38. Otros - importar proyectosdef fromPath(path: Path): Option[Project] =loaders.view.flatMap { load => load(path) }.headOption
  39. 39. Otros - importar proyectosdef fromPath(path: Path): Future[Option[Project]] =future {loaders.view.flatMap { load => load(path) }.headOption}
  40. 40. Otros - importar proyectosdef fromPath(path: Path): Future[Option[Project]] =future {loaders.view.flatMap { load => load(path) }.headOption}for {optP <- fromPath(path)p <- optP} {eventBus.publish(StatusMessage(s"Proj. ${p.name}"))}
  41. 41. sbtname := "sega"version := "2.0.0-SNAPSHOT"scalaVersion := "2.10.1"libraryDependencies <+= scalaVersion( "org.scala-lang" % "scala-swing" % _ )libraryDependencies ++= Seq("io.spray" %% "spray-json" % "1.2.3","com.github.scala-incubator.io" %% "scala-io-file" % "0.4.2","org.scalatest" %% "scalatest" % "1.9.1" % "test")
  42. 42. sbt - pluginsaddSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2")addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.7")
  43. 43. sbteclipseEclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE16)EclipseKeys.withSource := trueEclipseKeys.createSrc := EclipseCreateSrc.Default +EclipseCreateSrc.Resource
  44. 44. sbt-assemblyimport AssemblyKeys._assemblySettings// ... buil.sbt mostrado antes ...mainClass in assembly := Some("uy.edu.fing.inco.invop.ancap.sega.ui.Sega")packageOptions in assembly +=Package.ManifestAttributes("SplashScreen-Image" ->"uy/edu/fing/inco/invop/ancap/sega/splash.png")
  45. 45. Scala IDE for EclipsePlugin para desarrollo con Scala en EclipseUpdate site Eclipse Indigo y Scala 2.10http://download.scala-ide.org/sdk/e37/scala210/stable/site
  46. 46. Lo peorEl compilador es lentoLas herramientas de desarrollo consumenmucha memoria
  47. 47. Lo mejorSe puede empezar "pequeño" y crecer ademandaScala es escalable => nuestras aplicacionesson escalablesSe puede tener tipado estático y escribir pocoal mismo tiempo :)
  48. 48. ReferenciasScala generalhttp://docs.scala-lang.org/overviews/Scala-Swinghttp://www.scala-lang.org/sid/8http://ingomaier.blogspot.com/2010/11/scalaswing-package-in-28-and-beyond.htmlhttps://github.com/scala/scala/tree/master/docs/examples/swinghttps://github.com/benhutchison/ScalaSwingContribhttp://www.interactivemesh.org/testspace/j3dmeetsscala.htmlMVPhttps://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces
  49. 49. ReferenciasReactive programminghttps://github.com/ingoem/scala-reacthttps://github.com/nafg/reactive/tree/master/reactive-corehttp://infoscience.epfl.ch/record/176887/files/DeprecatingObservers2012.pdfhttp://etorreborre.blogspot.com/2011/10/counting-words-part-2.htmlScalaFXhttps://code.google.com/p/scalafx/https://github.com/rafonso/ProScalaFXspray-jsonhttps://github.com/spray/spray-json
  50. 50. ReferenciasScala IOhttp://jesseeichar.github.com/scala-io-doc/http://daily-scala.blogspot.com/2012/07/scala-io-getting-started.html (ysubsecuentes posts)ScalaTesthttp://www.scalatest.org/http://www.scalatest.org/user_guide/using_scalatest_with_eclipseSpecs²http://etorreborre.github.com/specs2/
  51. 51. Referenciasscala.sys.processhttp://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.sys.process.packagehttp://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.sys.process.ProcessBuilderPackratParsershttp://www.artima.com/pins1ed/combinator-parsing.htmlhttp://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.util.parsing.combinator.Parsershttp://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.util.parsing.combinator.PackratParsers
  52. 52. Referenciassbthttp://www.scala-sbt.org/https://github.com/paulp/sbt-extrashttps://github.com/sbt/sbt-assemblyhttps://github.com/typesafehub/sbteclipseScala IDE for Eclipsehttp://scala-ide.org/
  53. 53. :)Muchas gracias
  1. A particular slide catching your eye?

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

×