• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Scala en proyectos de vinculación Ancap-UR - 2013-03
 

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

on

  • 201 views

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 ...

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.

Statistics

Views

Total Views
201
Views on SlideShare
201
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • Experience report 2009 - 2013Scala en proyectos devinculación ANCAP-URGermán FerrariMarzo 2013@gerferrauy.linkedin.com/in/gerferra/
    • 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
    • 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: Entrada de datosCon el tiempoEjecución y monitoreo del solverReporte de resultadosScala
    • 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 friendlyBiblioteca estándarColeccionesProcesosParsersREPLComunidadFácil! para programadores Java ;)
    • Herramientas y bibliotecas usadasScala-Swingspray-jsonScala IOScalaTestscala.sys.processPackratParserssbt, sbt-assembly, sbteclipseScala IDE for Eclipse
    • Scala-SwingWrapper sobre SwingSe integra naturalmente en ScalaFeel declarativoAPI más simpleUsando MVP inspirado en el propuesto enGWTNo muy Scala-like pero funciona
    • Scala-Swing - ejemplosobject HelloWorld extends SimpleSwingApplication {def top = new MainFrame {title = "Hello, World!"contents = new Button {text = "Click Me!"}}}
    • Scala-Swing - ejemplosval b = new Button {text = "OK"font = fpreferredSize = (20, 20)}listenTo(b)reactions += {case ButtonClicked(`b`) => //reaction here}
    • 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}
    • 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
    • (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
    • 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]
    • 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])
    • 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)
    • 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
    • Scala IOEntrada / salida en ScalaManejo simple, portable, correcto y eficiente dearchivos y otros recursos de E/SComponentesIO BásicoArchivosAcceso asincrónicoProcessor
    • 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)
    • 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]}
    • 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))
    • 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
    • ScalaTestFramework de testingMultiples estilos de testTDD - FunSuiteBDD - FunSpecFeatureSpec
    • 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]}}
    • scala.sys.processAPI para ejecutar y controlar procesosIndicar qué correr y cómoManejar E/SCorrer procesoUtilizado para ejecución y monitoreo del solver
    • 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).!!
    • 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,"--check"))val logger = ProcessLogger { line =>onEDT { view.append(line) }}val proc = builder.run(logger)
    • PackratParsersConstrucción de parsers dentro del lenguajeAdmiten gramaticas recursivas por la izquierdaLos parsers comunes entran en loopExperimentos muy básicos de parsearentidades Mathprog
    • 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 ~ ")"}
    • 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
    • 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 ~ ")" ^^ { ??? } )}
    • PackratParsers - ejemploslazy val factor: PackratParser[Expr] = (floatingPointNumber ^^ { str => Num(str.toFloat) }| "(" ~> expr <~ ")")
    • 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)}
    • 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)
    • 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
    • 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(path) }.headOption}
    • 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}"))}
    • 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")
    • sbt - pluginsaddSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2")addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.7")
    • sbteclipseEclipseKeys.executionEnvironment := Some(EclipseExecutionEnvironment.JavaSE16)EclipseKeys.withSource := trueEclipseKeys.createSrc := EclipseCreateSrc.Default +EclipseCreateSrc.Resource
    • 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")
    • 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
    • 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 tener tipado estático y escribir pocoal mismo tiempo :)
    • 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
    • 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
    • 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/
    • 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
    • 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/
    • :)Muchas gracias