Your SlideShare is downloading. ×
0
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Scala @ TomTom
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Scala @ TomTom

2,818

Published on

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

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,818
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
34
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Scala @ TomTom<br />Eric Bowman<br />eric.bowman@tomtom.com<br />26 May 2010<br />
  • 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<br />
  • 4. 4<br />
  • 5. 5<br />Company Confidential<br /><ul><li>21,345 pages
  • 6. 40 reams of paper
  • 7. 5 laptops
  • 8. 8 keyboards
  • 9. 1 back operation
  • 10. 30,000 strands of hair</li></li></ul><li>6<br />
  • 11. 7<br />
  • 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. Sorting (sort merge remove-duplicates)
  • 14. Filtering (remove remove-if mapcan)
  • 15. Mapping (map mapcarmapc)
  • 16. Combining (reduce mapcan)
  • 17. Counting (count count-if)</li></ul>These functions abstract common control patterns. Code that uses them is:<br /><ul><li> Concise
  • 18. Self-documenting
  • 19. Easy to understand
  • 20. Often reusable
  • 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. 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. 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. What is this Scala thing?<br />11<br />
  • 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. Bi-Scalar Disorder<br />13<br />
  • 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. Keep Back<br />for (int i = 1; i <= 256; i++) {<br /> if (array[i-1] == ...<br />15<br />
  • 29. LOLCrash<br />16<br />
  • 30. Idioms<br />Reduce cognitive overhead<br />Reduce bugs<br />Make intention clear<br />Mini-Patterns<br />17<br />
  • 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. 19<br />
  • 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. For Comprehensions<br />Lists algorithmic “sweet spot”<br />Syntactic Sugar for:<br />foreach<br />map<br />filter<br />flatMap<br />21<br />
  • 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. 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. 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. 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. 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. Real-Life Example<br />“mntstamarg”<br />Each term has aliases<br />Need all permutations<br />27<br />
  • 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. 29<br />
  • 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. 31<br />
  • 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. 33<br />
  • 47. Discovering Fire<br />34<br />
  • 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. @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. 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. 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. 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. 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. 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. This slide left intentionally blank.<br />

×