Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Scala and WattzOn,
 Sitting in a Tree...
 Bay Area Scala Enthusiasts
         March 10, 2009
Who are we?
Jeremy Cloud   Raffi Krikorian
Who is Synthesis?

• Synthesis is a software and strategy
  consultancy
• Cambridge, MA
• 7 people
What is WattzOn?
           End User Perspective




• WattzOn is a free online tool to quantify,
  track, compare and und...
My Lifestyle: 14,504 Watts
What is WattzOn?
    Developer Perspective


                    scala-orm
WattzOn

                     scala-utils

 Hol...
What is Holmz?
• Object oriented “spread-sheet”
• Hierarchies of objects with properties
• Some properties are computed fr...
Holmz Understands
         Units

• Define a property as being “meters/second”
• Insert a value in “smoots/year”, and it wi...
Holmz DSL
Properties can be defined as simple algebraic
expressions over other properties within the
same object



     mp...
Holmz DSL
Properties can be defined as a reduction of
properties on other objects



   stuff_watts =
     for s in creator...
Holmz DSL
Formulas can contain extractor expressions for
decomposing other objects

component_rollup =
  for [count, comp]...
Parser Combinators
def cond = (or ~ opt(quot;?quot; ~> expr ~ (quot;:quot; ~> expr))) ^^ {
  case c ~ None => c
  case c ~...
Parser Combinators
• At first, appears to be line noise
• Terse
• Reasonably quick to write, once you
  understand them
• G...
Handwritten Parser

• About 6x faster
• About 6x the number of lines of code
• Better error reporting
Handwritten Parser
def cond = (or ~ opt(quot;?quot; ~> expr ~ (quot;:quot; ~> expr))) ^^ {
  case c ~ None => c
  case c ~...
Handwritten Parser

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




def or = {
  ts.fol...
Parser Combinators,
 To use or not to use
• Complexity of grammar
• Performance sensitivity
• Error reporting
• Readabilit...
What is WattzOn?
    Developer Perspective


                    scala-orm
WattzOn

                     scala-utils

 Hol...
What is scala-orm?

• native scala O/R mapping layer
• lightweight and fast
• XML schema in, generated scala code out
• un...
scala-orm schema
<table name=quot;EnumValuequot;>
  <field name=quot;versionquot; type=quot;intquot;/>
  <field name=quot;...
scala-orm output

• data object class
• data accessor object
• low overhead read, write, delete methods
• no reflection
scala idioms


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

•   def getAll(ids: ID*)(implicit session: Sd...
dynamic query builder

def getRecentlyAnswered(n: Int):
  JList[WorksheetAnswers] =
{
  DomainObject.query.where(quot;doma...
What is WattzOn?
    Developer Perspective


                    scala-orm
WattzOn

                     scala-utils

 Hol...
What is scala-utils?


• miscellaneous utility classes
• JavaBridge
JavaBridge


• Interacting with java collections is
  cumbersome in scala
Java Lists w/o JavaBridge
        Feels like Java 1.3 or earlier

import java.util.{List => JList}

def painful(jlist: JLi...
JavaBridge
import java.lang.{Iterable=>JIterable}

object JavaBridge {
  implicit def jit2sit[T](jit:JIterable[T]):Iterabl...
Java Lists w/ JavaBridge

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

def easy(jlist: JList[String]) = {
  for (...
Java Maps w/o
            JavaBridge
import java.util.{map => JMap}

def painful(jmap: JMap[String,String]) = {
  val iter...
JavaBridge
import java.util.{Map=>JMap}

object JavaBridge {
  ...
  implicit def jmap2sit[K,V](jmap:JMap[K,V]):Iterable[(...
Java Maps w/ JavaBridge

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

def easy(jmap: JMap[String,String]) = {
  for...
Java Maps w/o JavaBridge

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

def painful(): JMap[String,String] = {
  val att...
JavaBridge
import java.collection.{HashMap=>JHashMap, Map=>JMap}

object JavaBridge {
  ...
  def jmap[A, B](elems: (A, B)...
Java Maps w/ JavaBridge

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

def easy(): JMap[String,String] = {
  jmap(“fir...
Questions?

• www.wattzon.com
• www.synthesisstudios.com
• jeremy.cloud@synthesisstudios.com
• raffi.krikkorian@synthesisst...
Upcoming SlideShare
Loading in …5
×

Scala + WattzOn, sitting in a tree....

3,146 views

Published on

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)

Published in: Technology, News & Politics
  • Be the first to comment

Scala + WattzOn, sitting in a tree....

  1. 1. Scala and WattzOn, Sitting in a Tree... Bay Area Scala Enthusiasts March 10, 2009
  2. 2. Who are we? Jeremy Cloud Raffi Krikorian
  3. 3. Who is Synthesis? • Synthesis is a software and strategy consultancy • Cambridge, MA • 7 people
  4. 4. What is WattzOn? End User Perspective • 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
  5. 5. My Lifestyle: 14,504 Watts
  6. 6. What is WattzOn? Developer Perspective scala-orm WattzOn scala-utils Holmz swag
  7. 7. 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
  8. 8. 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]
  9. 9. Holmz DSL Properties can be defined as simple algebraic expressions over other properties within the same object mpg = miles / gallon
  10. 10. Holmz DSL Properties 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]
  11. 11. Holmz DSL Formulas 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]
  12. 12. Parser Combinators def cond = (or ~ opt(quot;?quot; ~> expr ~ (quot;:quot; ~> expr))) ^^ { case c ~ None => c case c ~ Some(t ~ e) => Conditional(c, t, e) } def or = chainl1(and, quot;||quot; ~> and, success{(a:AST, b:AST)=>Or(a,b)}) def and = chainl1(rel, quot;&&quot; ~> rel, success{(a:AST, b:AST)=>And(a,b)})
  13. 13. 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
  14. 14. Handwritten Parser • About 6x faster • About 6x the number of lines of code • Better error reporting
  15. 15. Handwritten Parser def cond = (or ~ opt(quot;?quot; ~> expr ~ (quot;:quot; ~> expr))) ^^ { case c ~ None => c case c ~ Some(t ~ e) => Conditional(c, t, e) } def cond = { ts.foldOpt(or) { case (c, SyntaxToken(quot;?quot;, _)) => val t = expr ts.syntax(quot;:quot;) val e = expr Conditional(c, t, e) } }
  16. 16. Handwritten Parser def or = chainl1(and, quot;||quot; ~> and, success{(a:AST, b:AST)=>Or(a,b)}) def or = { ts.fold(and) { case (left, SyntaxToken(quot;||quot;, _)) => Or(left, and) } }
  17. 17. Parser Combinators, To use or not to use • Complexity of grammar • Performance sensitivity • Error reporting • Readability a wash
  18. 18. What is WattzOn? Developer Perspective scala-orm WattzOn scala-utils Holmz swag
  19. 19. What is scala-orm? • native scala O/R mapping layer • lightweight and fast • XML schema in, generated scala code out • unimaginative name
  20. 20. scala-orm schema <table name=quot;EnumValuequot;> <field name=quot;versionquot; type=quot;intquot;/> <field name=quot;enumTypequot; type=quot;EnumTypequot;/> <field name=quot;keyquot; type=quot;stringquot;/> <field name=quot;displayNamequot; type=quot;stringquot;/> <field name=quot;descriptionquot; type=quot;stringquot; size=quot;0,65535quot;/> <field name=quot;creatorquot; type=quot;Userquot;/> <index fields=quot;enumType, keyquot; unique=quot;truequot;/> </table>
  21. 21. scala-orm output • data object class • data accessor object • low overhead read, write, delete methods • no reflection
  22. 22. scala idioms • def get(id: ID)(implicit session: SdbSession): Option[T] • def getAll(ids: ID*)(implicit session: SdbSession): Stream[T]
  23. 23. dynamic query builder def getRecentlyAnswered(n: Int): JList[WorksheetAnswers] = { DomainObject.query.where(quot;domainquot; -> domain). innerJoin(quot;creatorquot;, quot;confirmedquot; -> true). orderBy(quot;createdAtquot; -> false). limit(n).query.all.map(getOrUpdateAnswers) }
  24. 24. What is WattzOn? Developer Perspective scala-orm WattzOn scala-utils Holmz swag
  25. 25. What is scala-utils? • miscellaneous utility classes • JavaBridge
  26. 26. JavaBridge • Interacting with java collections is cumbersome in scala
  27. 27. Java Lists w/o JavaBridge Feels like Java 1.3 or earlier import java.util.{List => JList} def painful(jlist: JList[String]) = { val iter = jlist.iterator while (iter.hasNext) { val elt = iter.next ... }
  28. 28. 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.hasNext def next = baseIter.next } } } ... }
  29. 29. Java Lists w/ JavaBridge import java.util.{List => JList} import JavaBridge._ def easy(jlist: JList[String]) = { for (elt <- jlist) { ... } }
  30. 30. Java Maps w/o JavaBridge import java.util.{map => JMap} def painful(jmap: JMap[String,String]) = { val iter = jmap.entrySet.iterator while (iter.hasNext) { val entry = iter.next val key = entry.getKey val value = entry.getValue ... } }
  31. 31. JavaBridge import 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()) } } } ... }
  32. 32. Java Maps w/ JavaBridge import java.util.{map => JMap} import JavaBridge._ def easy(jmap: JMap[String,String]) = { for ((key, value) <- jmap) { ... } }
  33. 33. 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 }
  34. 34. 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 } ... }
  35. 35. Java Maps w/ JavaBridge import java.util.{Map=>JMap} import JavaBridge._ def easy(): JMap[String,String] = { jmap(“firstName” -> “Jeremy”, “lastName” -> “Cloud”) }
  36. 36. Questions? • www.wattzon.com • www.synthesisstudios.com • jeremy.cloud@synthesisstudios.com • raffi.krikkorian@synthesisstudios.com

×