scala + wattzon, sitting in a tree

36
Bay Area Scala Enthusiasts Scala and WattzOn, Sitting in a Tree... March 10, 2009

Upload: raffi-krikorian

Post on 25-Dec-2014

2.368 views

Category:

Technology


1 download

DESCRIPTION

A talk given to Scala enthusiasts at the Twitter HQ on using Scala in a real world environments (we get paid to write in Scala)

TRANSCRIPT

Page 1: Scala + WattzOn, sitting in a tree

Bay Area Scala Enthusiasts

Scala and WattzOn,Sitting in a Tree...

March 10, 2009

Page 2: Scala + WattzOn, sitting in a tree

Who are we?

Jeremy Cloud Raffi Krikorian

Page 3: Scala + WattzOn, sitting in a tree

Who is Synthesis?

• Synthesis is a software and strategy consultancy

• Cambridge, MA

• 7 people

Page 4: Scala + WattzOn, sitting in a tree

What is WattzOn?

• WattzOn is a free online tool to quantify, track, compare and understand the total amount of energy needed to support all of the facets of your lifestyle

End User Perspective

Page 5: Scala + WattzOn, sitting in a tree

My Lifestyle: 14,504 Watts

Page 6: Scala + WattzOn, sitting in a tree

What is WattzOn?Developer Perspective

WattzOn

Holmz

scala-orm

scala-utils

swag

Page 7: Scala + WattzOn, sitting in a tree

What is Holmz?

• Object oriented “spread-sheet”

• Hierarchies of objects with properties

• Some properties are computed from formulas over other objects and properties

• Sophisticated formula language (DSL)

• Intended as back-end for other systems

Page 8: Scala + WattzOn, sitting in a tree

Holmz Understands Units

• Define a property as being “meters/second”

• Insert a value in “smoots/year”, and it will auto convert

• (5 [gal] * 50[MJ/L] / 4[h]) @ [W]

Page 9: Scala + WattzOn, sitting in a tree

Holmz DSLProperties can be defined as simple algebraic expressions over other properties within the same object

mpg = miles / gallon

Page 10: Scala + WattzOn, sitting in a tree

Holmz DSLProperties can be defined as a reduction of properties on other objects

stuff_watts = for s in creator.worksheets.profile_stuff select sum(s.watts) default 0[W]

Page 11: Scala + WattzOn, sitting in a tree

Holmz DSLFormulas can contain extractor expressions for decomposing other objects

component_rollup = for [count, comp] in components

let [trans_watts, _*] = item_to_country(comp, made_in)

select sum(count * (comp.watts + trans_watts)), sum(count * comp.mass), sum(count * comp.disposal_watts)

default 0[W], 0[kg], 0[W]

Page 12: Scala + WattzOn, sitting in a tree

Parser Combinators

def cond = (or ~ opt("?" ~> expr ~ (":" ~> expr))) ^^ {case c ~ None => ccase c ~ Some(t ~ e) => Conditional(c, t, e)

}

def or = chainl1(and, "||" ~> and, success{(a:AST, b:AST)=>Or(a,b)})

def and = chainl1(rel, "&&" ~> rel, success{(a:AST, b:AST)=>And(a,b)})

Page 13: Scala + WattzOn, sitting in a tree

Parser Combinators

• At first, appears to be line noise

• Terse

• Reasonably quick to write, once you understand them

• Gets a bit hairy for complex grammars

• Error handling is difficult

• Performance is so-so

Page 14: Scala + WattzOn, sitting in a tree

Handwritten Parser

• About 6x faster

• About 6x the number of lines of code

• Better error reporting

Page 15: Scala + WattzOn, sitting in a tree

Handwritten Parser

def cond = {ts.foldOpt(or) {case (c, SyntaxToken("?", _)) =>val t = exprts.syntax(":")val e = exprConditional(c, t, e)

}}

def cond = (or ~ opt("?" ~> expr ~ (":" ~> expr))) ^^ {case c ~ None => ccase c ~ Some(t ~ e) => Conditional(c, t, e)

}

Page 16: Scala + WattzOn, sitting in a tree

Handwritten Parser

def or = {ts.fold(and) {case (left, SyntaxToken("||", _)) => Or(left, and)

}}

def or = chainl1(and, "||" ~> and, success{(a:AST, b:AST)=>Or(a,b)})

Page 17: Scala + WattzOn, sitting in a tree

Parser Combinators,To use or not to use

• Complexity of grammar

• Performance sensitivity

• Error reporting

• Readability a wash

Page 18: Scala + WattzOn, sitting in a tree

What is WattzOn?Developer Perspective

WattzOn

Holmz

scala-orm

scala-utils

swag

Page 19: Scala + WattzOn, sitting in a tree

What is scala-orm?

• native scala O/R mapping layer

• lightweight and fast

• XML schema in, generated scala code out

• unimaginative name

Page 20: Scala + WattzOn, sitting in a tree

scala-orm schema

<table name="EnumValue"><field name="version" type="int"/><field name="enumType" type="EnumType"/><field name="key" type="string"/><field name="displayName" type="string"/><field name="description" type="string" size="0,65535"/>

<field name="creator" type="User"/><index fields="enumType, key" unique="true"/>

</table>

Page 21: Scala + WattzOn, sitting in a tree

scala-orm output

• data object class

• data accessor object

• low overhead read, write, delete methods

• no reflection

Page 22: Scala + WattzOn, sitting in a tree

scala idioms

• def get(id: ID)(implicit session: SdbSession): Option[T]

• def getAll(ids: ID*)(implicit session: SdbSession): Stream[T]

Page 23: Scala + WattzOn, sitting in a tree

dynamic query builder

def getRecentlyAnswered(n: Int): JList[WorksheetAnswers] =

{DomainObject.query.where("domain" -> domain).innerJoin("creator", "confirmed" -> true).orderBy("createdAt" -> false).limit(n).query.all.map(getOrUpdateAnswers)

}

Page 24: Scala + WattzOn, sitting in a tree

What is WattzOn?Developer Perspective

WattzOn

Holmz

scala-orm

scala-utils

swag

Page 25: Scala + WattzOn, sitting in a tree

What is scala-utils?

• miscellaneous utility classes

• JavaBridge

Page 26: Scala + WattzOn, sitting in a tree

JavaBridge

• Interacting with java collections is cumbersome in scala

Page 27: Scala + WattzOn, sitting in a tree

Java Lists w/o JavaBridge

import java.util.{List => JList}

def painful(jlist: JList[String]) = {val iter = jlist.iteratorwhile (iter.hasNext) {val elt = iter.next...

}

Feels like Java 1.3 or earlier

Page 28: Scala + WattzOn, sitting in a tree

JavaBridge

import java.lang.{Iterable=>JIterable}

object JavaBridge {implicit def jit2sit[T](jit:JIterable[T]):Iterable[T] = {new Iterable[T] { def elements:Iterator[T] = new Iterator[T] {

val baseIter = jit.iterator()def hasNext = baseIter.hasNextdef next = baseIter.next

}}

}...

}

Page 29: Scala + WattzOn, sitting in a tree

Java Lists w/ JavaBridge

import java.util.{List => JList}import JavaBridge._

def easy(jlist: JList[String]) = {for (elt <- jlist) {...

}}

Page 30: Scala + WattzOn, sitting in a tree

Java Maps w/o JavaBridge

import java.util.{map => JMap}

def painful(jmap: JMap[String,String]) = {val iter = jmap.entrySet.iteratorwhile (iter.hasNext) {val entry = iter.nextval key = entry.getKeyval value = entry.getValue...

}}

Page 31: Scala + WattzOn, sitting in a tree

JavaBridgeimport java.util.{Map=>JMap}

object JavaBridge {...implicit def jmap2sit[K,V](jmap:JMap[K,V]):Iterable[(K,V)] = new Iterable[(K,V)] {def elements:Iterator[(K,V)] = new Iterator[(K,V)] { val baseIter = jmap.entrySet.iterator

def hasNext = baseIter.hasNext def next = { val entry = baseIter.next()

(entry.getKey(), entry.getValue()) } }}...

}

Page 32: Scala + WattzOn, sitting in a tree

Java Maps w/ JavaBridge

import java.util.{map => JMap}import JavaBridge._

def easy(jmap: JMap[String,String]) = {for ((key, value) <- jmap) {...

}}

Page 33: Scala + WattzOn, sitting in a tree

Java Maps w/o JavaBridge

import java.util.{HashMap=>JHashMap,Map=>JMap}

def painful(): JMap[String,String] = {val attrs = new JHashMap[String,String]attrs.put(“firstName”, “Jeremy”)attrs.put(“lastName”, “Cloud”attrs

}

Page 34: Scala + WattzOn, sitting in a tree

JavaBridge

import java.collection.{HashMap=>JHashMap, Map=>JMap}

object JavaBridge {...def jmap[A, B](elems: (A, B)*): JMap[A,B] = {val map = new JHashMap[A,B](elems.size * 2)for ((k, v) <- elems) map.put(k, v)map

}...

}

Page 35: Scala + WattzOn, sitting in a tree

Java Maps w/ JavaBridge

import java.util.{Map=>JMap}import JavaBridge._

def easy(): JMap[String,String] = {jmap(“firstName” -> “Jeremy”,“lastName” -> “Cloud”)

}

Page 36: Scala + WattzOn, sitting in a tree

Questions?

• www.wattzon.com

• www.synthesisstudios.com

[email protected]

[email protected]