Scala @ TomTom<br />Eric Bowman<br />eric.bowman@tomtom.com<br />26 May 2010<br />
What’s He Building In There?<br />Not just PNDs<br />Traffic Services<br />Location Services<br />Address & Local Search<b...
3<br />
4<br />
5<br />Company Confidential<br /><ul><li>21,345 pages
40 reams of paper
5 laptops
8 keyboards
1 back operation
30,000 strands of hair</li></li></ul><li>6<br />
7<br />
Tutorial on Good Lisp Programming Style<br />8<br />“Most algorithms can be characterized as:<br /><ul><li>  Searching (so...
  Sorting (sort merge remove-duplicates)
  Filtering (remove remove-if mapcan)
  Mapping (map mapcarmapc)
  Combining (reduce mapcan)
  Counting (count count-if)</li></ul>These functions abstract common control patterns. Code that uses them is:<br /><ul><l...
  Self-documenting
  Easy to understand
  Often reusable
  Usually efficient”</li></ul>    From Peter Norvig’sTutorial on Good Lisp Programming Style, 1993     <br />    (http://w...
But...<br />“Lisp is good for:<br />Exploratory programming<br />Rapid prototyping<br />Minimizing time-to-market<br />Sin...
I Like<br />Static types<br />Refactoring Tools<br />Lazy Sundays<br />Paying Some Kid To Cut The Grass<br />Spreadsheets<...
What is this Scala thing?<br />11<br />
Scala Is...<br />An escaped research language from EPFL targeting JVM and CLR<br />Object-oriented and functional<br />Sta...
Bi-Scalar Disorder<br />13<br />
Functional Programming?<br />Functions as first class objects<br />Immutability<br />Closures<br />Binding free variables ...
Keep Back<br />for (int i = 1; i <= 256; i++) {<br />   if (array[i-1] == ...<br />15<br />
LOLCrash<br />16<br />
Idioms<br />Reduce cognitive overhead<br />Reduce bugs<br />Make intention clear<br />Mini-Patterns<br />17<br />
Java Idioms<br />++C++<br />No more 0xDEADBEEF<br />Leads to lots of loops and copies, if you’re doing it right<br />Hard ...
19<br />
For Comprehensions<br />for(inti=0; i<100; i++) { ... }<br />for (i <- 0 until 100) { <br />... /* do something with i */ ...
For Comprehensions<br />Lists algorithmic “sweet spot”<br />Syntactic Sugar for:<br />foreach<br />map<br />filter<br />fl...
The Easy Ones<br />for (i <- 1 to 6) yield i * 2<br />(1 to 6).map(_ * 2)<br />	(2,4,6,8,10,12)<br />for (i <- 1 to 6 if i...
A Harder One...<br />List<Integer> array = new ArrayList<Integer>();<br />for (i = 1; i <= 3; i++) {<br />  for (j = i; j ...
flatMap<br />Subtle thing...<br />“Applies the given function f to each element, then concatenates the results”<br />Turns...
IteratorIterator<br />package org.hyperic.sigar.util; <br />public static class IteratorIteratorimplements java.util.Itera...
flatMapflatMap<br />def foo(arg: Iterable[Int]) {<br />    ... Do something with arg<br />}<br />val some: Iterable[Int] =...
Real-Life Example<br />“mntstamarg”<br />Each term has aliases<br />Need all permutations<br />27<br />
Java Version<br />static List<String> aliasReplace(String place) { <br />        String[] bits = nospaces.split(place); <b...
29<br />
Upcoming SlideShare
Loading in...5
×

Scala @ TomTom

2,845

Published on

Slides from Eric Bowman's talk at the Dutch Scala Enthusiast's (DUSE) meeting at Tomtom HQ in Amsterdam, 26 May 2010.

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

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

No notes for slide

Scala @ TomTom

  1. 1. Scala @ TomTom<br />Eric Bowman<br />eric.bowman@tomtom.com<br />26 May 2010<br />
  2. 2. What’s He Building In There?<br />Not just PNDs<br />Traffic Services<br />Location Services<br />Address & Local Search<br />Tons of Data -> Tons of Analysis<br />Deep Commitment to Server-Side Java<br />2<br />
  3. 3. 3<br />
  4. 4. 4<br />
  5. 5. 5<br />Company Confidential<br /><ul><li>21,345 pages
  6. 6. 40 reams of paper
  7. 7. 5 laptops
  8. 8. 8 keyboards
  9. 9. 1 back operation
  10. 10. 30,000 strands of hair</li></li></ul><li>6<br />
  11. 11. 7<br />
  12. 12. Tutorial on Good Lisp Programming Style<br />8<br />“Most algorithms can be characterized as:<br /><ul><li> Searching (some find find-if mismatch)
  13. 13. Sorting (sort merge remove-duplicates)
  14. 14. Filtering (remove remove-if mapcan)
  15. 15. Mapping (map mapcarmapc)
  16. 16. Combining (reduce mapcan)
  17. 17. Counting (count count-if)</li></ul>These functions abstract common control patterns. Code that uses them is:<br /><ul><li> Concise
  18. 18. Self-documenting
  19. 19. Easy to understand
  20. 20. Often reusable
  21. 21. Usually efficient”</li></ul> From Peter Norvig’sTutorial on Good Lisp Programming Style, 1993 <br /> (http://www.norvig.com/luv-slides.ps)<br />
  22. 22. But...<br />“Lisp is good for:<br />Exploratory programming<br />Rapid prototyping<br />Minimizing time-to-market<br />Single-programmer (or single-digit team) projects<br />Source-to-source or data-to-data transformation” (ibid.)<br />9<br />
  23. 23. I Like<br />Static types<br />Refactoring Tools<br />Lazy Sundays<br />Paying Some Kid To Cut The Grass<br />Spreadsheets<br />Not Flying The Plane<br />10<br />
  24. 24. What is this Scala thing?<br />11<br />
  25. 25. Scala Is...<br />An escaped research language from EPFL targeting JVM and CLR<br />Object-oriented and functional<br />Statically typed<br />Lisp, ML, Haskell, Erlang, etc.<br />DSL-friendly<br />12<br />
  26. 26. Bi-Scalar Disorder<br />13<br />
  27. 27. Functional Programming?<br />Functions as first class objects<br />Immutability<br />Closures<br />Binding free variables to enclosing lexical scope <br />Higher-order Functions<br />functions as input and/or output<br />A different set of idioms...<br />14<br />
  28. 28. Keep Back<br />for (int i = 1; i <= 256; i++) {<br /> if (array[i-1] == ...<br />15<br />
  29. 29. LOLCrash<br />16<br />
  30. 30. Idioms<br />Reduce cognitive overhead<br />Reduce bugs<br />Make intention clear<br />Mini-Patterns<br />17<br />
  31. 31. Java Idioms<br />++C++<br />No more 0xDEADBEEF<br />Leads to lots of loops and copies, if you’re doing it right<br />Hard programs get complex doing common things<br />Nested loops begin to look Harmful...<br />18<br />
  32. 32. 19<br />
  33. 33. For Comprehensions<br />for(inti=0; i<100; i++) { ... }<br />for (i <- 0 until 100) { <br />... /* do something with i */ }<br />(0.until(100)).foreach(i => <br /> /* something with i */)<br />20<br />
  34. 34. For Comprehensions<br />Lists algorithmic “sweet spot”<br />Syntactic Sugar for:<br />foreach<br />map<br />filter<br />flatMap<br />21<br />
  35. 35. The Easy Ones<br />for (i <- 1 to 6) yield i * 2<br />(1 to 6).map(_ * 2)<br /> (2,4,6,8,10,12)<br />for (i <- 1 to 6 if i % 2 == 0) yield i<br />(1 to 6).filter(_ % 2 == 0)<br /> (2,4,6)<br />for (i <- 1 to 6) { println(i + “ “) }<br />(1 to 6).foreach { i => print(i + “ “) }<br /> 1 2 3 4 5 6<br />22<br />
  36. 36. A Harder One...<br />List<Integer> array = new ArrayList<Integer>();<br />for (i = 1; i <= 3; i++) {<br /> for (j = i; j <= 3; j++) {<br />array.add(j);<br /> }<br />}<br />System.out.println(array);<br />[1, 2, 3, 2, 3, 3]<br />for (i <- 1 to 3; j <- i to 3) yield j<br />(1, 2, 3, 2, 3, 3)<br />(1 to 3).flatMap(i => (i to 3).map(j => j)) <br />23<br />
  37. 37. flatMap<br />Subtle thing...<br />“Applies the given function f to each element, then concatenates the results”<br />Turns a list of lists into a list<br />List(List(1,2,3), List(4,5,6)).flatMap(x => x)<br />List(1, 2, 3, 4, 5, 6)<br />List(“tom”, “tom”).flatMap(_.capitalize).mkString<br />TomTom<br />“Special sauce” for nested looping constructs<br />(Equivalent to Haskell’s monadic “bind”)<br />24<br />
  38. 38. IteratorIterator<br />package org.hyperic.sigar.util; <br />public static class IteratorIteratorimplements java.util.Iterator { <br />private java.util.ArrayListiterators; <br />public IteratorIterator() {} <br />public void add(java.util.Iteratoriterator) {} <br />public booleanhasNext() {} <br />public java.lang.Object next() {} <br /> public void remove() {} <br />}<br />25<br />
  39. 39. flatMapflatMap<br />def foo(arg: Iterable[Int]) {<br /> ... Do something with arg<br />}<br />val some: Iterable[Int] = getSomeIterable<br />foo(some)<br />val more: Iterable[Int] = getMore<br />foo(List(some, more).flatMap(x => x))<br />26<br />
  40. 40. Real-Life Example<br />“mntstamarg”<br />Each term has aliases<br />Need all permutations<br />27<br />
  41. 41. Java Version<br />static List<String> aliasReplace(String place) { <br /> String[] bits = nospaces.split(place); <br /> List<String> result = new ArrayList<String>(); <br /> List<StringBuilder> allAliases = new ArrayList<StringBuilder>(); <br />for (String bit : bits) { <br /> String[] ales = aliases.get(bit); <br />if (ales != null) { <br /> if (allAliases.size() == 0) { <br />allAliases.add(new StringBuilder(bit)); <br />for (String alias : ales) { <br />allAliases.add(new StringBuilder(alias)); <br /> } <br /> } <br />else { <br /> List<StringBuilder> clones = new <br />ArrayList<StringBuilder>(); <br />for (StringBuilder a : allAliases) { <br />clones.add(new StringBuilder(a).append(" ").append( <br /> bit)); <br />for (String alias : ales) { <br />clones.add(new StringBuilder(a).append(" ").append( <br /> alias)); <br /> } <br /> } <br />allAliases = clones; <br /> } <br /> } <br />else { <br />if (allAliases.size() == 0) { <br />allAliases.add(new StringBuilder(bit)); <br /> } <br />else { <br />for (StringBuilder b : allAliases) { <br />b.append(" ").append(bit); <br /> } <br /> } <br /> } <br /> } <br />for (StringBuildermunge: allAliases) { <br />result.add(munge.toString()); <br /> } <br />return result; <br /> }<br />28<br />
  42. 42. 29<br />
  43. 43. Scala Version<br />def alias(query: String, aliases: String => List[String]): List[String] = {<br /> def recurse(prefix: List[String], remainder: List[String]): List[List[String]] = {<br /> remainder match {<br /> case Nil => prefix :: Nil<br />case head :: tail => aliases(head).flatMap(term => recurse(term :: prefix, tail))<br /> }<br />recurse(Nil,query.split(“”).toList.reverse).map(<br /> _.mkString(“ “))<br />}<br />30<br />
  44. 44. 31<br />
  45. 45. Yeah yeahyeah but<br />“Perl Whitespace Law” <br />“Each line of perl should be surrounded by whitespace equivalent to what it would take to achieve the same functionality in a normal programming language.” -- Don Hopkins<br />If it compiles, it nearly works. Really.<br />Visual Plane-Oriented Programming<br />I ♥ Idioms<br />“But in Java, each little part is so very simple...”<br />32<br />
  46. 46. 33<br />
  47. 47. Discovering Fire<br />34<br />
  48. 48. “Weak developers will move heaven and earth to do the wrong thing. You can’t limit the damage they do by locking up the sharp tools. They’ll just swing the blunt tools harder.” – Glenn Vandenburg<br />35<br />
  49. 49. @TomTom<br />Testing<br />Middleware “Smart Content Switch”<br />We needed it quickly...<br />B2B/B2G Traffic Query Engine<br />Clustering Algorithm<br />DSL Templating Engine<br />Content Cleanup<br />Next-Generation Geocoder<br />36<br />
  50. 50. How To Sneak It In<br />Start with Testing<br />ScalaCheckIS AWESOME.<br />Specs, ScalaTest testing DSLs<br />Start with something low risk<br />Ok, well, we didn’t do that<br />Prepare for steep learning curve<br />...followed by a productivity hockey stick<br />37<br />
  51. 51. Another Example<br />8000 lines of broken Java -> 400 lines of broken Scala -><br />hyp.take(1).flatMap(_.dropDistricts) match {<br /> case Nil => hyp<br /> case head => {<br />hyp.tail.foldLeft(head) {<br />case (run: List[Hypothesis], h: Hypothesis) => { <br />run.flatMap(_.merge(h)) match {<br /> case Nil => run <br />case newRun => newRun.removeDuplicates<br />}<br /> }<br /> }<br /> }<br />}<br />*Includes suggested improvements by Martin Odersky, I hope<br />38<br />
  52. 52. Testing<br />Functional architect wrote a bunch of test cases, like:<br />Requirement R.17:<br />D1 -> N1, L1 -> N1, N1, D2 -> L2, L3, N3, D3 should cluster as (L1,N1,D1), (L2,D2), (L3), (N3), (D3)<br />Vim-macro’d into:<br />it should “satisfy R.17” in {<br /> cluster(D1 -> N1,L1 -> N1,N1,D2 -> L2,L3,N3,D3) should equal {<br />groups(group(L1,N1,D1),group(L2,D2),group(L3),group(N3),<br />group(D3)))<br />}<br />39<br />
  53. 53. ScalaCheck<br />The Dog’s Bollocks<br />Steep Learning Curve<br />object BinarySpecification extends Properties(“bin”) {<br /> specify(“toBinary”,<br />Prop.forAllNoShrink(<br /> for{n <- Gen.choose(0d, 0.99999999d)<br /> m <- Gen.choose(20,31) } yield Pair(n, m)) {<br /> p => <br />Math.abs(toDecimal(toBinary(p._1, p._2)) – p._1 < 1e-10 <br /> })}<br />40<br />
  54. 54. So little time...<br />Traits<br />Case classes<br />Pattern matching<br />Structural types<br />Self types<br />XML<br />Option<br />Covariance/Contravariance<br />@specialized<br />41<br />
  55. 55. This slide left intentionally blank.<br />
  1. A particular slide catching your eye?

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

×