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,036 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
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,036
On SlideShare
0
From Embeds
0
Number of Embeds
52
Actions
Shares
0
Downloads
51
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

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

×