Refactoring to Scala DSLs and LiftOff 2009 Recap

download Refactoring to Scala DSLs and LiftOff 2009 Recap

If you can't read please download the document

Transcript of Refactoring to Scala DSLs and LiftOff 2009 Recap

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

Facebook

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