Refactoring to Scala DSLs and LiftOff 2009 Recap

  • 2,246 views
Uploaded on

An introductory presentation given to the Chicago Area Scala Enthusiasts (a) beginning with a recap of the Scala LiftOff unconference in Reston, VA, 2009, and (b) describing how to gradually migrate …

An introductory presentation given to the Chicago Area Scala Enthusiasts (a) beginning with a recap of the Scala LiftOff unconference in Reston, VA, 2009, and (b) describing how to gradually migrate Scala code translated directly from Java into a DSL that facilitates readability and maintainability of client code. We then observe that this technique makes it possible to use Scala DSLs as a way to introduce Scala in a Java shop.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
2,246
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
62
Comments
1
Likes
4

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 LiftOff Recap and Refactoring to DSLs by David Orme Eclipse, Rich web, and Scala consulting [email_address] Presented to Chicago Area Scala Enthusiasts CASE
  • 2. Meeting Agenda
    • Agenda:
      • Scala LiftOff Recap
      • 3. Refactoring to DSLs
        • Techniques for migrating to Scala
  • 4. Meeting Agenda
    • Agenda:
      • Scala LiftOff Recap
      • 5. Refactoring to DSLs
        • Techniques for migrating to Scala
  • 6. Scala LiftOff
    • Unconference format
      • Began with Martin Odersky prepared keynote
      • 7. (Some) Attendees came prepared to speak
        • Created the schedule
        • 8. People made suggestions/improvements
        • 9. Sessions were voluntarily merged
        • 10. ...then we did it
      • With so many really smart people present, it worked very well
  • 11. Scala LiftOff
    • Overall themes:
      • Scala 2.8 improvements
      • 12. Enterprise adoption: Status and opportunities
      • 13. Killer applications / uses
      • 14. Thinking in functions
  • 15. Scala LiftOff
    • Overall themes:
      • Scala 2.8 improvements
      • 16. Enterprise adoption: Status and opportunities
      • 17. Killer applications / uses
      • 18. Thinking in functions
  • 19. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • New collections
        • Consistency between mutable/immutable implementations with a single abstract parent defining the API for both
        • 20. Paid off technical debt – eliminated implementation duplication throughout the library
        • 21. Consistent implcit conversions to and from Java collections and Scala collections
  • 22. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • Named parameters
      • 23. def resize(width: Int, height: Int) = { ... }
      • 24. resize(width = 120, height = 42) resize(height = 42, width = 120)
  • 25. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • Default parameter values
      • 26. def f(elems: List[Int], x: Int = 0, cond: Boolean = true)
      • 27. f(List(1))
      • 28. f(Nil, cond = false)
  • 29. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • break is now implemented … as a library function!
      • 30. import scala.util.control.Breaks._
      • 31. breakable {
      • 32. for (x <- elems) {
      • 33. println(x*2)
      • 34. if (x > 0) break
      • 35. }
      • 36. }
  • 37. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • New and improved tool support
        • New tooling supported directly in scala compiler
        • 38. Brand new, much more stable Eclipse plugin.
        • 39. Tight Java tooling integration
        • 40. No more ”Project/Clean” or closing/reopening projects to reboot the compiler!
        • 41. Same tool support also ported to NetBeans
        • 42. Martin definitely ”gets it” about the importance of having high quality Scala tool support
  • 43. Scala LiftOff
    • Scala 2.8 – Selected Improvements
      • Dave's verdict:
        • Important changes at all levels of the Scala stack
        • 44. 2.8 could be what causes Scala to cross the chasm into the mainstream
  • 45. Scala LiftOff
    • Overall themes:
      • Scala 2.8 improvements
      • 46. Enterprise adoption: Status and opportunities
      • 47. Killer applications / uses
      • 48. Thinking in functions
  • 49. Scala LiftOff
    • Enterprises that have adopted Scala
      • Web 2.0 startups
      • Financial industry, particularly in trading
        • EDF Trading
        • 53. Clarify
        • 54. Swiss Quote
        • 55. (some smaller financial firms)
  • 56. Scala LiftOff
    • How to introduce into an enterprise?
      • Non-Prod uses
        • More readable unit/integration tests
        • 57. Build tooling, database loading, scripting, etc...
      • Production uses
        • A targeted module in a larger system
        • 58. Often a DSL of some form
  • 59. Scala LiftOff
    • Remaining challenges
      • Commercial support
        • Formal training
        • 60. Someone to sue
        • 61. This situation is improving, especially in Europe
      • Tooling (IDEs, CI infrastructure)
        • 2.8 significantly improves this
      • Licensing (perceived challenge)
        • If it's free, it can't be any good
        • 62. Yes, some people still say this, even in 2009!
  • 63. Scala LiftOff
    • Overall themes:
      • Scala 2.8 improvements
      • 64. Enterprise adoption: Status and opportunities
      • 65. Killer applications / uses
      • 66. Thinking in functions
  • 67. Scala LiftOff
    • Killer Applications/Uses
      • DSLs in particular; more generally, anywhere greater abstraction is useful/needed
      • 68. XML processing
        • (since XML is a part of native Scala syntax)
        • 69. Content-management systems
        • 70. Web templating engines
      • Testing
        • Specs, ScalaCheck
      • Build, development lifecycle tooling
        • SBT keeps coming up!
  • 71. Scala LiftOff
    • Overall themes:
      • Scala 2.8 improvements
      • 72. Enterprise adoption: Status and opportunities
      • 73. Killer applications / uses
      • 74. Thinking in functions
  • 75. Scala LiftOff
    • Thinking in Functions
      • This thought came up again and again:
        • Java (OO/Procedural) programs are a series of state mutations
          • Change objects' state in-place; the ”result value” changes over time
          • 76. A, A', A'', A''', … , A (n)
  • 77. Scala LiftOff
    • Thinking in Functions
      • This thought came up again and again:
        • Functional-style programs are a series of state transformations
          • Transform one result to another repeatedly over time
          • 78. A -> B -> C -> D -> … -> Z
        • Notice how the identity/value of A always stays the same
        • 79. Notice how this helps with threading and concurrency!
  • 80. Scala LiftOff
    • Thinking in Functions
      • This thought came up again and again:
        • Functional-style programs are a series of state transformations
          • Transform one result to another repeatedly over time
          • 81. A -> B -> C -> D -> … -> Z
      • See also: Rich Hickey's presentation on InfoQ:
        • Are we there yet?
          • http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey?utm_source=twitterfeed&utm_medium=twitter
  • 82. Scala LiftOff
    • Thinking in Functions
      • Ironically, LIFTWeb is a very stateful (OO-style) framework.
      • 83. -> Make sure that your load-balancing server uses sticky sessions (that the same session always goes to the same server)
  • 84. Scala LiftOff
    • Any questions about the Scala LiftOff?
    • 85. Overall themes:
      • Scala 2.8 improvements
      • 86. Enterprise adoption: Status and opportunities
      • 87. Killer applications / uses
      • 88. Thinking in functions
  • 89. Meeting Agenda
    • Agenda:
      • Scala LiftOff Recap
      • 90. Refactoring to DSLs
        • Techniques for migrating to Scala
  • 91. Refactoring to DSLs
    • Refactoring to DSLs: Why?
      • A good way to introduce Scala
      • 92. Provides visible, incremental benefits
  • 93. Refactoring to DSLs
    • Refactoring to DSLs: How?
      • Start with something painful or impossible in Java
      • 94. Translate the basic idea into Scala
      • 95. Apply Scala idiom(s) to improve code
      • 96. ”Can we do better?”
      • 97. Lather, rinse, repeat...
  • 98. Refactoring to DSLs
    • Example: The O/S Shell DSL
      • Simple file operations
      • 99. Running O/S command and processing results
        • I.e.: Perl ”back-tick operator” with variable contents interpolation
          • @files = `ls $install_dir`
          • 100. -> List files in $install_dir; place into @files array
  • 101. Refactoring to DSLs
    • @files = `ls $install_dir`
      • Can we make Scala do (something like) this?
  • 102. Refactoring to DSLs
    • @files = `ls $install_dir`
      • Interpolate variable contents into strings
      • 103. Run a shell command and return results
      • 104. Avoid cluttering code with
        • new File(”something”)
      • line noise when we already know we're working with files anyway
  • 105. Refactoring to DSLs
    • @files = `ls $install_dir`
      • Interpolate variable contents into strings
        • Translate the basic idea into Scala
        • 106. Apply Scala idiom(s) to improve code
        • 107. ”Can we do better?”
        • 108. Lather, rinse, repeat...
  • 109. Refactoring to DSLs
    • Start with: The Java Way, translated to Scala
    • 110. val folder = &quot;/home&quot;;
    • 111. println(&quot;ls &quot; + folder)
    • 112. Can we do better?
      • Not easily–if we start from this syntax
      • 113. Plan B: Is there a way to interpolate ANYTHING into a String using regular Java or Scala?
  • 114. Refactoring to DSLs
    • What about this idea?
    • 115. val folder = &quot;/home&quot;;
    • 116. val formatter = new java.util.Formatter()
    • 117. println(formatter.format(&quot;ls %s&quot;, folder))
      • Pro: Now we're actually interpolating into the string
      • 118. Con: More verbose!
        • Can we do better?
  • 119. Refactoring to DSLs
    • What about this idea?
    • 120. val folder = &quot;/home&quot;;
    • 121. val formatter = new java.util.Formatter()
    • 122. println(formatter. format (&quot;ls %s&quot;, folder))
      • What if we use Scala implicits to add the format method to java.lang.String?
  • 123. Refactoring to DSLs
    • Actually, Scala does that for us already. ;-P
    • 124. val folder = &quot;/home&quot;;
    • 125. println(&quot;ls %s&quot;.format(folder))
      • Notice: In order to refactor TO a DSL, all we need to do is to switch the format method to use infix notation
  • 126. Refactoring to DSLs
    • Actually, Scala does that for us already. ;-P
    • 127. val folder = &quot;/home&quot;;
    • 128. println(&quot;ls %s&quot;.format(folder))
    • 129. println(&quot;ls %s&quot; format folder)
  • 130. Refactoring to DSLs
    • Actually, Scala does that for us already. ;-P
    • 131. val folder = &quot;/home&quot;;
    • 132. println(&quot;ls %s&quot;.format(folder))
    • 133. println(&quot;ls %s&quot; format folder)
      • Pros: This isn't bad OO code
      • 134. Cons: Asking a String (a data structure) to format another string, when it's really substituting that other string into itself doesn't seem right.
        • Can we do better?
  • 135. Refactoring to DSLs
    • Add our own implicit conversion supplying synonyms for the #format method
    • 136. val folder = &quot;/home&quot;;
    • 137. println(&quot;ls %s&quot; substituting folder)
    • 138. println(&quot;ls %s&quot; << folder)
    • 139. Notice: We have now created a simple DSL for variable interpolation into strings.
  • 140. Refactoring to DSLs
    • Let's go play with the code. :-)
  • 141. Refactoring to DSLs
    • @files = `ls $install_dir`
      • Interpolate variable contents into strings
      • 142. Run a shell command and return results
        • Translate the basic idea into Scala
        • 143. Apply Scala idiom(s) to improve code
        • 144. ”Can we do better?”
        • 145. Lather, rinse, repeat...
  • 146. Refactoring to DSLs
    • Start with: The Java Way, translated to Scala
    • 147. new PlatformExec(&quot;cat /etc/hosts&quot;).execPrint()
      • Write a class that encapsulates Runtime.exec() nastiness
      • 148. Instantiate it
      • 149. Execute a method on it
        • Can we do better?
  • 150. Refactoring to DSLs
    • What if we make that big OO thing into a single function call?
    • 151. execute(&quot;cat /etc/passwd&quot;)
      • Pros: Definitely simpler/easier to read
      • 152. Cons: Still not nearly as convenient as back-tick notation
        • Can we do better?
  • 153. Refactoring to DSLs
    • What if we add the execute method directly to java.lang.String using Scala's implicit type conversions?
      • This enables us to write this:
      • 154. for (line <- &quot;ls&quot;.exec().split(&quot; &quot;)) {
      • 155. println(&quot;-> &quot; + line)
      • 156. }
  • 157. Refactoring to DSLs
    • What if we add the execute method directly to java.lang.String as a lexically-scoped implicit?
      • Or this:
      • 158. &quot;ls&quot;.exec().split(&quot; &quot;).foreach { file =>
      • 159. println(&quot;=> &quot; + file)
      • 160. }
    • Not bad. And sometimes this is perfect.
      • But sometimes we just want a backtick operator!
        • Can we do better?
  • 161. Refactoring to DSLs
    • We can add methods to java.lang.String, and operators are just methods.
    • 162. Is there an operator that could reasonably mean ”execute” to a String?
  • 163. Refactoring to DSLs
    • How about unary_! as Scala's backtick operator? Then we can write:
      • !&quot;cat /etc/passwd&quot;
    • Or:
      • val name = &quot;Dave&quot; !(&quot;echo I'm sorry, %s, I just can't do that&quot; substituting name)
      • 164. Pro: We now have a reasonable ”backtick” operator, and a lot of OO/FP flexibility as well.
      • 165. Con: A lot of these operations would be better done with a straight java.io.File
        • Can we do better?
  • 166. Refactoring to DSLs
    • @files = `ls $install_dir`
      • Interpolate variable contents into strings
      • 167. Run a shell command and return results
      • 168. Avoid cluttering code with
        • new File(”something”)
      • line noise when we already know we're working with files anyway
  • 169. Refactoring to DSLs
    • Simply add an implicit conversion converting a java.lang.String into a java.io.File:
      • implicit def string2File(s : String) = new java.io.File(s)
    • Then we can write:
      • for (file <- &quot;/home/djo&quot;.list()) { println(&quot;==> %s&quot; << file) }
  • 170. Refactoring to DSLs
    • Simply add an implicit conversion converting a java.lang.String into a java.io.File:
      • implicit def string2File(s : String) = new java.io.File(s)
    • Then we can write:
      • for (file <- &quot;/home/djo&quot;.list()) { println(&quot;=> %s&quot; << file) }
    • Or even:
    • 171. &quot;/home/djo&quot;.list.foreach(println(&quot;=> %s&quot; << _) )
  • 172. Refactoring to DSLs
    • Let's go play with the code. :-)
  • 173. Refactoring to DSLs
    • By carefully applying Scala idioms, we find ourselves naturally refactoring our code into a DSL that fits our problem domain
      • -> Use Scala's infix notation to make OO code read like English
      • 174. -> Wrap repetitive Java code in ”bridge classes”
      • 175. -> When appropriate, make those ”bridge classes” available via implicit conversions
      • 176. -> Carefully use operator overloading
  • 177. Refactoring to DSLs
    • By carefully applying Scala idioms, we find ourselves naturally refactoring our code into a DSL that fits our problem domain
    • 178. This provides us with a simple, repeatable migration path off of Java, onto Scala
  • 179. CASE
    • Questions? Comments?
    • 180. Presentation available on SlideShare