refactoring to scala dsls and liftoff 2009 recap
TRANSCRIPT
Scala LiftOff RecapandRefactoring to DSLs
by David OrmeEclipse, Rich web, and Scala [email protected]
Presented to Chicago Area Scala Enthusiasts
CASE
Meeting Agenda
Agenda:Scala LiftOff Recap
Refactoring to DSLsTechniques for migrating to Scala
Meeting Agenda
Agenda:Scala LiftOff Recap
Refactoring to DSLsTechniques for migrating to Scala
Scala LiftOff
Unconference formatBegan with Martin Odersky prepared keynote
(Some) Attendees came prepared to speakCreated the schedule
People made suggestions/improvements
Sessions were voluntarily merged
...then we did it
With so many really smart people present, it worked very well
Scala LiftOff
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Scala LiftOff
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Scala LiftOff
Scala 2.8 Selected ImprovementsNew collectionsConsistency between mutable/immutable implementations with a single abstract parent defining the API for both
Paid off technical debt eliminated implementation duplication throughout the library
Consistent implcit conversions to and from Java collections and Scala collections
Scala LiftOff
Scala 2.8 Selected ImprovementsNamed parameters
def resize(width: Int, height: Int) = { ... }
resize(width = 120, height = 42)
resize(height = 42, width = 120)
Scala LiftOff
Scala 2.8 Selected ImprovementsDefault parameter values
def f(elems: List[Int],
x: Int = 0,
cond: Boolean = true)f(List(1))f(Nil, cond = false)
Scala LiftOff
Scala 2.8 Selected Improvementsbreak is now implemented as a library function!import scala.util.control.Breaks._breakable { for (x 0) break }}
Scala LiftOff
Scala 2.8 Selected ImprovementsNew and improved tool supportNew tooling supported directly in scala compiler
Brand new, much more stable Eclipse plugin.
Tight Java tooling integration
No more Project/Clean or closing/reopening projects to reboot the compiler!
Same tool support also ported to NetBeans
Martin definitely gets it about the importance of having high quality Scala tool support
Scala LiftOff
Scala 2.8 Selected ImprovementsDave's verdict:Important changes at all levels of the Scala stack
2.8 could be what causes Scala to cross the chasm into the mainstream
Scala LiftOff
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Scala LiftOff
Enterprises that have adopted ScalaWeb 2.0 startupsTwitter
RTM
...
Financial industry, particularly in tradingEDF Trading
Clarify
Swiss Quote
(some smaller financial firms)
Scala LiftOff
How to introduce into an enterprise?Non-Prod usesMore readable unit/integration tests
Build tooling, database loading, scripting, etc...
Production usesA targeted module in a larger system
Often a DSL of some form
Scala LiftOff
Remaining challengesCommercial supportFormal training
Someone to sue
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
Yes, some people still say this, even in 2009!
Scala LiftOff
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Scala LiftOff
Killer Applications/UsesDSLs in particular; more generally, anywhere greater abstraction is useful/needed
XML processing(since XML is a part of native Scala syntax)
Content-management systems
Web templating engines
TestingSpecs, ScalaCheck
Build, development lifecycle toolingSBT keeps coming up!
Scala LiftOff
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Scala LiftOff
Thinking in FunctionsThis thought came up again and again:Java (OO/Procedural) programs are a series of state mutationsChange objects' state in-place; the result value changes over time
A, A', A'', A''', , A(n)
Scala LiftOff
Thinking in FunctionsThis thought came up again and again:Functional-style programs are a series of state transformationsTransform one result to another repeatedly over time
A B C D Z
Notice how the identity/value of A always stays the same
Notice how this helps with threading and concurrency!
Scala LiftOff
Thinking in FunctionsThis thought came up again and again:Functional-style programs are a series of state transformationsTransform one result to another repeatedly over time
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
Scala LiftOff
Thinking in FunctionsIronically, LIFTWeb is a very stateful (OO-style) framework.
Make sure that your load-balancing server uses sticky sessions (that the same session always goes to the same server)
Scala LiftOff
Any questions about the Scala LiftOff?
Overall themes:Scala 2.8 improvements
Enterprise adoption: Status and opportunities
Killer applications / uses
Thinking in functions
Meeting Agenda
Agenda:Scala LiftOff Recap
Refactoring to DSLsTechniques for migrating to Scala
Refactoring to DSLs
Refactoring to DSLs: Why?A good way to introduce Scala
Provides visible, incremental benefits
Refactoring to DSLs
Refactoring to DSLs: How?Start with something painful or impossible in Java
Translate the basic idea into Scala
Apply Scala idiom(s) to improve code
Can we do better?
Lather, rinse, repeat...
Refactoring to DSLs
Example: The O/S Shell DSLSimple file operations
Running O/S command and processing resultsI.e.: Perl back-tick operator with variable contents interpolation@files = `ls $install_dir`
List files in $install_dir; place into @files array
Refactoring to DSLs
@files = `ls $install_dir`Can we make Scala do (something like) this?
Refactoring to DSLs
@files = `ls $install_dir`Interpolate variable contents into strings
Run a shell command and return results
Avoid cluttering code with new File(something)
line noise when we already know we're working with files anyway
Refactoring to DSLs
@files = `ls $install_dir`Interpolate variable contents into stringsTranslate the basic idea into Scala
Apply Scala idiom(s) to improve code
Can we do better?
Lather, rinse, repeat...
Refactoring to DSLs
Start with: The Java Way, translated to Scalaval folder = "/home";println("ls " + folder)
Can we do better?Not easilyif we start from this syntax
Plan B: Is there a way to interpolate ANYTHING into a String using regular Java or Scala?
Refactoring to DSLs
What about this idea?val folder = "/home";val formatter = new java.util.Formatter()println(formatter.format("ls %s", folder))
Pro: Now we're actually interpolating into the string
Con: More verbose!
Can we do better?
Refactoring to DSLs
What about this idea?val folder = "/home";val formatter = new java.util.Formatter()println(formatter.format("ls %s", folder))
What if we use Scala implicits to add the format method to java.lang.String?
Refactoring to DSLs
Actually, Scala does that for us already. ;-Pval folder = "/home";println("ls %s".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
Refactoring to DSLs
Actually, Scala does that for us already. ;-Pval folder = "/home";println("ls %s".format(folder))println("ls %s" format folder)
Refactoring to DSLs
Actually, Scala does that for us already. ;-Pval folder = "/home";println("ls %s".format(folder))println("ls %s" format folder)Pros: This isn't bad OO code
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?
Refactoring to DSLs
Add our own implicit conversion supplying synonyms for the #format methodval folder = "/home";println("ls %s" substituting folder)println("ls %s" println("=> " + file)}
Not bad. And sometimes this is perfect.But sometimes we just want a backtick operator!Can we do better?
Refactoring to DSLs
We can add methods to java.lang.String, and operators are just methods.
Is there an operator that could reasonably mean execute to a String?
Refactoring to DSLs
How about unary_! as Scala's backtick operator? Then we can write:!"cat /etc/passwd"
Or:val name = "Dave"
!("echo I'm sorry, %s, I just can't do that"
substituting name)Pro: We now have a reasonable backtick operator,
and a lot of OO/FP flexibility as well.
Con: A lot of these operations would be better done with a straight java.io.FileCan we do better?
Refactoring to DSLs
@files = `ls $install_dir`Interpolate variable contents into strings
Run a shell command and return results
Avoid cluttering code with new File(something)
line noise when we already know we're working with files anyway
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