An Introduction to                                Scala for Java                                Programmers               ...
In 2003, Martin Odersky and his team set                          out to create a “scalable” language that                ...
Scalable LanguageThursday, November 25, 2010
Scalable LanguageThursday, November 25, 2010
Thursday, November 25, 2010
Scalable Language                    object Hello {                    	 def main(args:Array[String]) {                   ...
Scalable Language                                  mention linkedin connect with jruby front and scala back               ...
Scala loves Java                              import javax.servlet.http.HttpServlet                              import ja...
Java loves Scala                        class CrazyScalaTechnology {                          def doWebThreeDotOhStuff(msg...
Highly interoperable                               with Java                   • To your boss and the people who          ...
Scala is OO                   • Classes/Interfaces/Fields                   • Everything is an object                   • ...
Basics              class Account(var currentBalance:MonetaryAmount,              	 	 	 	       val accountOwner:Person,  ...
Basics                    class name/extensions                                                                field decla...
Basics                                class Account(var currentBalance:MonetaryAmount,                                	 	 ...
Basics                        extra class initialization                                                                  ...
Basics              class Account(var currentBalance:MonetaryAmount,              	 	 	 	       val accountOwner:Person,  ...
Basics: Accessing your                               fields                              val account = new Account(balance,...
public class Account implements IAccount {                                    private MonetaryAmount currentBalance;      ...
Thursday, November 25, 2010
Everything is an object                   • No operators                   • No primitives                   • No arrays  ...
OO:                                  Inheritance                              trait Fruit {                              	...
OO: traits                   • “Interfaces with implementation”                   • Like interfaces, a class can extend ma...
OO: traits                     Special considerations                   • No initialization of fields with constructors    ...
OO: traits                   • 3 interesting uses of trait                    • Rich Interfaces                    • Stack...
Traits: Rich Interfaces                              trait Comparable[A] {                                def compare(that...
Traits: mixins                         /**                           * Throw an exception if someone calls get with       ...
Traits: mixins                         trait NoNullAccessMap[K, V] extends java.util.Map[K, V] {                          ...
Traits: mixins                              /**                                * Throw an exception if someone tries to ca...
Traits: mixins (static)                              class StrictMap[K, V] extends HashMap[K, V]                          ...
Traits: mixins (dynamic)                   val stateForCity = new HashMap[String, String]()                   	 	 	 	 	 	 ...
Traits: compose                                 functionality                                         class GetAccountsCon...
Food for thought                   • If you had traits, when would you choose                              inheritance and...
OO:                                            singletons                                     object CheckSums {          ...
OO:                                        singletons                   • Concise way to define a class AND create a       ...
Scala is OO                   • Scala is fairly consistent with Java in terms                              of simple OO co...
Scala is functional                  • Functions are first-class citizens                  • Immutability/No Side Effects  ...
Functional                                    programming                   • Imperative programs consist of statements   ...
Functional Scala:                        functions are objects                              def square(x:Int) = x * xThurs...
Functional Scala:                        functions are objects                              val squareFunction = new Funct...
Functional Scala:                        functions are objects                               val squareFunction = { x:Int ...
Functional Scala:                        functions are objects                              val squareFunction = { x:Int =...
Imperative Java                              public List<String> getShortCityNames(List<String cities) {                  ...
Functional Scala                         val cities = List("Richmond", "Charlottesville", "Ashland")                      ...
Functional Scala                         val shortCities = cities.filter { city => city.length < 8 }                      ...
Functional Scala                                        val shortCities = cities.filter { _.length < 8 }                  ...
Functional Scala                              Functional style                               val shortCities = cities.filt...
Functional Scala                              Functional style                               val shortCities = cities.filt...
Put the fun back in                                   functions                              val (minors, adults) = people...
Put the fun back in                                   functions                   //total salary for all employees in acco...
Put the fun back in                                   functions                    var clicks = 0                    react...
Custom control                                structures            public void transfer(Account fromAccount,            	...
Custom control                                structures                     public void transfer(Account fromAccount,    ...
19 lines - where’d my                              code go?         def transfer(fromAccount:Account, toAccount:Account, a...
Custom control                                structures                                unit is scala-speak for           ...
Why first-class                                    functions                   • Move boilerplate to library, increase     ...
I resisted list comprehensions when I first                   learned Python, and I resisted filter and map               ...
Scala is functional                   • Functions are first-class citizens                   • Immutability/No Side Effects...
What’s wrong with side                effects and mutability?                   • What do you hate about bad code?        ...
Mutability is surprising         	     	     Map<Widget, String> statusForWidget = new HashMap<Widget, String>();         ...
Mutability has unintended                     consequences                              	   private List<Widget> widgets =...
Mutability is hard to                               maintain                      public class Account {                  ...
Side effects can blow                             your mind            public class DateParseServlet extends HttpServlet {...
Why immutable and                           side-effect free?                   • Easier to reason about                  ...
Scala and Immutability                   • val vs. var                   • Collections library                   • ActorsT...
val vs. var                                 class Person(val first:String, val last:String)                   • This class...
Collections library                   • Scala provides two collection libraries:                              immutable an...
Actors                   • Scala preferred concurrent programming                              model                   • N...
Actors   object Accumulator extends Actor {                         Accumulator.start      def act = {                    ...
Food for thought                   • What effects does immutability have on                              performance?     ...
Scala is functional                   • Functions are first-class citizens                   • Immutability/Side Effects   ...
Pattern Matching                   • Pattern matching is a switch statement                    • Matching on properties of...
Pattern Matching                              def parseBoolean(a: Any):Boolean = {                                val stri...
Pattern Matching:                                Case Classes                   case class Town(city:String, state:String)...
Case classes are great                     for representing your                        “Data objects”:                   ...
case classes are great:                               copy                              val youngy = new Person("Youngy", ...
Express powerful                              concepts concisely                        case class Town(city:String, state...
class Person {                                                                                                         pub...
public class Town {                              	        public static Town Town(String city, String state) {            ...
Thursday, November 25, 2010
Scala is functional                   • Functions are first-class citizens                   • Immutability/Side Effects   ...
Type inference                   • Local variables                   • Return type                   • Type parametersThur...
More noise reduction                   • Semicolons                   • Dots                   • Braces                   ...
• How does type inference affect readability?                    reducing boilerplate is obvious win                    bu...
Extra innings                   • Option                   • Implicit conversions                   • Named parameters/def...
Where’s the bug?                              String name = getPerson("person1234").getName();Thursday, November 25, 2010
Where’s the bug?                              String name = getPerson("person1234").getName();                            ...
How do you know                          when a value is null?                   •      Great guesser               •   Us...
How do you know                          when a value is null?Thursday, November 25, 2010
Scala’s approach:                                 Option[T]                              def getPerson(id:String):Option[P...
Scala’s approach:                                    Option[T]                   • Option is extended by Some and None    ...
Scala’s approach:                                  Option[T]                          //previous approach: doesnt compile!...
Implicit conversions                   • Automatically convert types                   • Commonly used to add behavior to ...
Implicit Conversions                           A Rich Wrapper                              class RichInt(i:Int) {         ...
Implicit Conversions                              class RichInt(i:Int) {                              	 def times(f: => Un...
Named and default                                parameters                                def sendEmail(                 ...
Named and default                                parameters                  sendEmail(List("a@a.com"), "b@b.com")        ...
Out of time                   •      DSLs                 •   Currying                   •      Sane generics (no         ...
My top10 Aspects of                                Scala                   •      Java Interop             •   rich collec...
These concepts are in                     other statically typed                      JVM languages too!                  ...
Go try it!                   • http://scala-lang.org                   • http://www.simplyscala.com/ - try simple         ...
Thanks!                                   adamrabung@gmail.com                              http://squirrelsewer.blogspot....
Upcoming SlideShare
Loading in …5
×

Introduction to Scala for Java Programmers

1,416 views
1,438 views

Published on

The slide was originally prepared by "Adam Rabung" (http://www.slideshare.net/adamrabung/introduction-to-scala-for-java-programmers)

Paul Snively presented in SBJUG using this slide, on October 25 6:00PM. You can find the recorded talk here - http://www.youtube.com/watch?v=JiJ6B3LeVuk

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,416
On SlideShare
0
From Embeds
0
Number of Embeds
695
Actions
Shares
0
Downloads
32
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Introduction to Scala for Java Programmers

  1. 1. An Introduction to Scala for Java Programmers Adam RabungThursday, November 25, 2010
  2. 2. In 2003, Martin Odersky and his team set out to create a “scalable” language that fused important concepts from functional and object-oriented programming. The language aimed to be highly interoperable with Java, have a rich type system, and to allow developers to express powerful concepts concisely.Thursday, November 25, 2010
  3. 3. Scalable LanguageThursday, November 25, 2010
  4. 4. Scalable LanguageThursday, November 25, 2010
  5. 5. Thursday, November 25, 2010
  6. 6. Scalable Language object Hello { def main(args:Array[String]) { println("Hello World") } }Thursday, November 25, 2010
  7. 7. Scalable Language mention linkedin connect with jruby front and scala back mention using clojure data structures in scalaThursday, November 25, 2010
  8. 8. Scala loves Java import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse class ScalaServlet extends HttpServlet { override def doGet(request: HttpServletRequest, response: HttpServletResponse) { response.getWriter().println("Hello World!") } }Thursday, November 25, 2010
  9. 9. Java loves Scala class CrazyScalaTechnology { def doWebThreeDotOhStuff(msg:String) { println(msg) Scala } } public class JavaPojo { Java public static void main(String[] args) { new CrazyScalaTechnology().doWebThreeDotOhStuff("Hello world!"); } } eclipse supports mixed projects that can hold .scala and .java note the String being passed in to Java - in fact, most of the scala “stdlib” is just javasThursday, November 25, 2010
  10. 10. Highly interoperable with Java • To your boss and the people who administer your servers, it’s “just a jar” • Because it’s not an all or nothing proposition, you can slowly “sneak” Scala into your codebase - think test cases!Thursday, November 25, 2010
  11. 11. Scala is OO • Classes/Interfaces/Fields • Everything is an object • Traits • SingletonsThursday, November 25, 2010
  12. 12. Basics class Account(var currentBalance:MonetaryAmount, val accountOwner:Person, val withdrawalLimit:MonetaryAmount) { private val txLog = new TransactionLog() txLog.log(“New acct with “ + currentBalance) def getSummary = "Name = " + accountOwner.name + ", Balance = " + currentBalance def withdraw(amount:MonetaryAmount) { if (amount < currentBalance && amount < withdrawalLimit) currentBalance = currentBalance - amount else txLog.log("Withdrawal rejected, amount too high: " + amount) } }Thursday, November 25, 2010
  13. 13. Basics class name/extensions field declarations constructor + copying to fields class Account(var currentBalance:MonetaryAmount, val accountOwner:Person, val withdrawalLimit:MonetaryAmount) extends IAccount { private val txLog = new TransactionLog() txLog.log(“New acct with “ + currentBalance) def getSummary = "Name = " + accountOwner.name + ", Balance = " + currentBalance def withdraw(amount:MonetaryAmount) { if (amount < currentBalance && amount < withdrawalLimit) currentBalance = currentBalance - amount else txLog.log("Withdrawal rejected, amount too high: " + amount) } }Thursday, November 25, 2010
  14. 14. Basics class Account(var currentBalance:MonetaryAmount, val accountOwner:Person, val withdrawalLimit:MonetaryAmount) extends IAccount { • var means “variable” - readable and writeable. Automatically generates getters and setters • val means “value” - read-only. Generates only getters and the field is not re- assignable val does not mean “immutable”Thursday, November 25, 2010
  15. 15. Basics extra class initialization private field class Account(var currentBalance:MonetaryAmount, val accountOwner:Person, val withdrawalLimit:MonetaryAmount) extends IAccount { private val txLog = new TransactionLog() txLog.log(“New acct with “ + currentBalance) def getSummary = "Name = " + accountOwner.name + ", Balance = " + currentBalance def withdraw(amount:MonetaryAmount) { if (amount < currentBalance && amount < withdrawalLimit) currentBalance = currentBalance - amount else txLog.log("Withdrawal rejected, amount too high: " + amount) } }Thursday, November 25, 2010
  16. 16. Basics class Account(var currentBalance:MonetaryAmount, val accountOwner:Person, val withdrawalLimit:MonetaryAmount) { body of the class is the private val txLog = new TransactionLog() body of the constructor txLog.log(“New acct with “ + currentBalance) def getSummary = "Name = " + accountOwner.name + ", Balance = " + currentBalance def withdraw(amount:MonetaryAmount) { if (amount < currentBalance && amount < withdrawalLimit) currentBalance = currentBalance - amount else txLog.log("Withdrawal rejected, amount too high: " + amount) } }Thursday, November 25, 2010
  17. 17. Basics: Accessing your fields val account = new Account(balance, user, limit) account.currentBalance = new MonetaryAmount(50) println("New balance is " + account.currentBalance) account.accountOwner = new Person("Hacker Johnson") “Setter” “Getter” Won’t compile - accountOwner is a “val”Thursday, November 25, 2010
  18. 18. public class Account implements IAccount { private MonetaryAmount currentBalance; private final Person accountOwner; private final MonetaryAmount withdrawalLimit; private final TransactionLog txLog; public Account(MonetaryAmount currentBalance, Person accountOwner, MonetaryAmount withdrawalLimit ) { this.currentBalance = currentBalance; this.accountOwner = accountOwner; this.withdrawalLimit = withdrawalLimit; this.txLog = new TransactionLog(); txLog.log("New acct created"); } public String getSummary() { return "Name = " + accountOwner.name + ", Balance = " + currentBalance; } public void withdraw(MonetaryAmount amount) { if (amount.isLessThan(currentBalance) && amount.isLessThan(withdrawalLimit)) { currentBalance = currentBalance.minus(amount); } else { txLog.log("Withdrawal rejected, amount too high: " + amount); } } public MonetaryAmount getCurrentBalance() { return currentBalance; } public void setCurrentBalance(MonetaryAmount currentBalance) { this.currentBalance = currentBalance; } public Person getAccountOwner() { return accountOwner; } public MonetaryAmount getWithdrawalLimit() { return withdrawalLimit; } }Thursday, November 25, 2010
  19. 19. Thursday, November 25, 2010
  20. 20. Everything is an object • No operators • No primitives • No arrays • No statics did you notice me using < and - on MonetaryAmt?Thursday, November 25, 2010
  21. 21. OO: Inheritance trait Fruit { def getColor : String Fruit is an ifc def hasStem : Boolean Brief syntax } single expression methods can skip { override keyword class Apple extends Fruit { def getColor = "Red" default is public def hasStem = true } class GrannySmithApple extends Apple { override def getColor = "Green" }Thursday, November 25, 2010
  22. 22. OO: traits • “Interfaces with implementation” • Like interfaces, a class can extend many traits • Like abstract classes, a trait can define abstract and concrete methods - multiple inheritance!!Thursday, November 25, 2010
  23. 23. OO: traits Special considerations • No initialization of fields with constructors • Special meaning of “super”: • In Java, known when you compile the class • With traits, known only when you mix it inThursday, November 25, 2010
  24. 24. OO: traits • 3 interesting uses of trait • Rich Interfaces • Stackable modifications/”mixins” • Compose diverse functionality into a single unitThursday, November 25, 2010
  25. 25. Traits: Rich Interfaces trait Comparable[A] { def compare(that: A): Int Abstract def < (that: A): Boolean = (this compare that) < 0 def > (that: A): Boolean = (this compare that) > 0 def <= (that: A): Boolean = (this compare that) <= 0 def >= (that: A): Boolean = (this compare that) >= 0 } did you notice? method names w/ special chars missing dots and parens? this is just an abstract class, but you dont have to feel guilty about mixing it inThursday, November 25, 2010
  26. 26. Traits: mixins /** * Throw an exception if someone calls get with * an undefined key */ trait NoNullAccessMap[K, V] extends java.util.Map[K, V] { abstract override def get(key: Object): V = { val value = super.get(key) assert(value != null, "No value found for key " + key) return value } }Thursday, November 25, 2010
  27. 27. Traits: mixins trait NoNullAccessMap[K, V] extends java.util.Map[K, V] { abstract override def get(key: Object): V = { val value = super.get(key) assert(value != null, "No value found for key " + key) return value } } The exact functionality you are overriding is not yet knownThursday, November 25, 2010
  28. 28. Traits: mixins /** * Throw an exception if someone tries to call put() * with a key that is already in the map */ trait NoOverwriteMap[K, V] extends java.util.Map[K, V] { abstract override def put(key: K, value: V): V = { assert(!containsKey(key), "Could not set " + key + " to " + value + ": it is already set to " + get(key)) return super.put(key, value) } }Thursday, November 25, 2010
  29. 29. Traits: mixins (static) class StrictMap[K, V] extends HashMap[K, V] with NoNullAccessMap[K, V] with NoOverwriteMap[K, V] now that we’re creating a real class, we use HashMap not MapThursday, November 25, 2010
  30. 30. Traits: mixins (dynamic) val stateForCity = new HashMap[String, String]() with NoNullAccessMap[String, String] with NoOverwriteMap[String, String] pick and choose characteristics for individual map instancesThursday, November 25, 2010
  31. 31. Traits: compose functionality class GetAccountsController extends Controllor with PermissionCheck with Logging of course, java style composition is fine tooThursday, November 25, 2010
  32. 32. Food for thought • If you had traits, when would you choose inheritance and when would you choose composition?Thursday, November 25, 2010
  33. 33. OO: singletons object CheckSums { def calculateMD5(s:String) = "todo!" } def main(args:Array[String]) { CheckSums.calculateMD5("password") } concise way to define a class and “singletonize” Item 1:Consider it update this to use an interface providing static factory methods instead of contructorsThursday, November 25, 2010
  34. 34. OO: singletons • Concise way to define a class AND create a singleton instance of it • Used for “static” methods • Thread-safe instantiation • Extend traits or classes! • Used exactly like any objectThursday, November 25, 2010
  35. 35. Scala is OO • Scala is fairly consistent with Java in terms of simple OO concepts like classes, fields, and polymorphism • Scala takes OO further with concepts like traits, everything-is-an-object, uniform access principle, etc.Thursday, November 25, 2010
  36. 36. Scala is functional • Functions are first-class citizens • Immutability/No Side Effects These concepts are very important in java of course • Pattern matching • Type inferenceThursday, November 25, 2010
  37. 37. Functional programming • Imperative programs consist of statements that change state • Functional programs evaluate expressions and avoid using state and mutable data I no longer make software. I make lenses for the projection of data. :) @nuttycomThursday, November 25, 2010
  38. 38. Functional Scala: functions are objects def square(x:Int) = x * xThursday, November 25, 2010
  39. 39. Functional Scala: functions are objects val squareFunction = new Function1[Int, Int]() { def apply(x: Int) = x * x } functions can be values just like Strings and ints of course, no different than java hereThursday, November 25, 2010
  40. 40. Functional Scala: functions are objects val squareFunction = { x:Int => x * x } Is just shorthand for val squareFunction = new Function1[Int, Int]() { def apply(x:Int) = x * x }Thursday, November 25, 2010
  41. 41. Functional Scala: functions are objects val squareFunction = { x:Int => x * x } val squareFunction = new Function1[Int, Int]() { def apply(x:Int) = x * x }Thursday, November 25, 2010
  42. 42. Imperative Java public List<String> getShortCityNames(List<String cities) { List<String> shortCityNames = new ArrayList<String>(); for (String city : cities) { if (city.length() < 8) { shortCityNames.add(city); } } return shortCityNames; } “imperative” as the opposite of “functional” you might obser ve whats going on here is we’re taking a list of items, and filtering out those that do not match a conditionThursday, November 25, 2010
  43. 43. Functional Scala val cities = List("Richmond", "Charlottesville", "Ashland") val shortCities = cities.filter { city: String => city.length < 8 } //now shortCities has just Ashland", cities is unchanged Passing a function into a function! pass the transformation into the collection Great type inference for Function types there’s “=>” againThursday, November 25, 2010
  44. 44. Functional Scala val shortCities = cities.filter { city => city.length < 8 } more type inference - scala already knows the type of “city”, since cities is a List[String]Thursday, November 25, 2010
  45. 45. Functional Scala val shortCities = cities.filter { _.length < 8 } scala uses “_” as the all of these examples placeholder variable, for compile down to the when naming the same code variable doesnt help its a matter of style like “it” in groovy when considering how much inference to useThursday, November 25, 2010
  46. 46. Functional Scala Functional style val shortCities = cities.filter { _.length < 8 } Imperative style List<String> shortCities = getShortCityNames(cities); public List<String> getShortCityNames(List<String cities) { List<String> shortCityNames = new ArrayList<String>(); for (String city : cities) { if (city.length() < 8) { shortCityNames.add(city); } } return shortCityNames; } This is where bugs liveThursday, November 25, 2010
  47. 47. Functional Scala Functional style val shortCities = cities.filter { _.length < 8 } This is where bugs liveThursday, November 25, 2010
  48. 48. Put the fun back in functions val (minors, adults) = people partition (_.age < 18) make t wo lists out of 1, based on a predicate multiple assignmentThursday, November 25, 2010
  49. 49. Put the fun back in functions //total salary for all employees in accounting val totalSalaryForAccountingDept = employees .filter(_.dept == "Accounting") .map(_.salary) .sum Here, “map” takes a list of important to note these are creating new collections, not Employee objects, and modifying “employees” creates a List of salariesThursday, November 25, 2010
  50. 50. Put the fun back in functions var clicks = 0 reactions += { case ButtonClicked(b) => clicks += 1 label.text = "Number of button clicks: "+ clicks }Thursday, November 25, 2010
  51. 51. Custom control structures public void transfer(Account fromAccount, Account toAccount, MonetaryAmount amount) { where’s the bugs? Transaction t = null; try { t = acquireTransaction(); fromAccount.debit(amount); toAccount.credit(amount); t.commit(); } catch (Exception e) { throw new RuntimeException("Failed to transfer ", e); } finally { t.close(); } }Thursday, November 25, 2010
  52. 52. Custom control structures public void transfer(Account fromAccount, Account toAccount, MonetaryAmount amount) { Transaction t = null; try { t = acquireTransaction(); fromAccount.debit(amount); toAccount.credit(amount); t.commit(); } catch (Exception e) { t.rollback(); throw new RuntimeException("Failed to transfer ", e); } finally { if (t != null) { t.close(); } } }Thursday, November 25, 2010
  53. 53. 19 lines - where’d my code go? def transfer(fromAccount:Account, toAccount:Account, amount:MonetaryAmount) { transaction { fromAccount.debit(amount) toAccount.credit(amount) } }Thursday, November 25, 2010
  54. 54. Custom control structures unit is scala-speak for void this is a function that takes nothing and def transaction(transactionCode: => Unit) { returns nothing val transaction = null try { transaction = acquireTransaction() transactionCode transaction.commit Just pass in the code } catch { case e: Exception => that should be in TX transaction.rollback throw new RuntimeException("Tx failed: rolled back", e) } finally { if (transaction != null) { transaction.close } } }Thursday, November 25, 2010
  55. 55. Why first-class functions • Move boilerplate to library, increase readability • Less “book-keeping” and mutable variables means less bugs • All the advantages of libraries over boilerplate: better tuning, quality, better imagine these operations abstractions being executed in parallel on a multicoreThursday, November 25, 2010
  56. 56. I resisted list comprehensions when I first learned Python, and I resisted filter and map even longer. I insisted on making my life more difficult, sticking to the familiar way of for loops and if statements and step-by-step code-centric programming. And my Python programs looked a lot like Visual Basic programs, detailing every step of every operation in every function. And they had all the same types of little problems and obscure bugs. And it was all pointless. — Mark Pilgrim, Dive into Python, §16.5Thursday, November 25, 2010
  57. 57. Scala is functional • Functions are first-class citizens • Immutability/No Side Effects • Pattern matching • Type inferenceThursday, November 25, 2010
  58. 58. What’s wrong with side effects and mutability? • What do you hate about bad code? • No seperation of concerns • Variables changing from many different paths • Hard to test or reason about • Control flow is all over the placeThursday, November 25, 2010
  59. 59. Mutability is surprising Map<Widget, String> statusForWidget = new HashMap<Widget, String>(); Widget w = new Widget("Whiz", 12); statusForWidget.put(w, "operational"); w.setName("Whizzer"); System.out.println(statusForWidget.get(w)); //Null! why doesnt this work?Thursday, November 25, 2010
  60. 60. Mutability has unintended consequences private List<Widget> widgets = loadWidgets(); //...... public List<Widget> getAllWidgets() { return widgets; } thing.getAllWidgets().remove(0); “trust boundaries” think about someone downstream calling “retainAll” on your widgets fieldThursday, November 25, 2010
  61. 61. Mutability is hard to maintain public class Account { private int amount; public Account() { } public String getSummary() { //can i safely use amount here? return "Account currently has " + amount + " dollars"; } public void setAmount(int amount) { this.amount = amount; } }Thursday, November 25, 2010
  62. 62. Side effects can blow your mind public class DateParseServlet extends HttpServlet { private DateFormat dateParser = new SimpleDateFormat("yyyyMMdd"); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { resp.getWriter().print( dateParser.format(req.getParameter("dateString"))); } } Where’s the bug? item #13 in “effective java”Thursday, November 25, 2010
  63. 63. Why immutable and side-effect free? • Easier to reason about • No need to worry about what callers do with data they get from you • We live in a multi-threaded worldThursday, November 25, 2010
  64. 64. Scala and Immutability • val vs. var • Collections library • ActorsThursday, November 25, 2010
  65. 65. val vs. var class Person(val first:String, val last:String) • This class is immutable - first and last are read-only • val does NOT means “immutable”: it means “non-reassignable” or “final”. Your class is only immutable if it’s “vals all the way down”Thursday, November 25, 2010
  66. 66. Collections library • Scala provides two collection libraries: immutable and mutable • immutable is “default”Thursday, November 25, 2010
  67. 67. Actors • Scala preferred concurrent programming model • No Runnable, synchronized, no locks, no shared mutable state - a “developer- centric” approach • Modeled from ErlangThursday, November 25, 2010
  68. 68. Actors object Accumulator extends Actor { Accumulator.start def act = { for(i <- (1 to 100)) { var sum = 0 async { loop { react { Shared state Accumulator ! Accumulate(i) } case Accumulate(n) => sum += n } case Reset => sum = 0 case Total => reply(sum); exit Accumulator !? Total; match { } case result: Int => println(result) } } } } Lots of threads hitting the actor actors are “shared nothing” - messages are immutable mutable state is privateThursday, November 25, 2010
  69. 69. Food for thought • What effects does immutability have on performance? • What effects does immutability have on correctness?Thursday, November 25, 2010
  70. 70. Scala is functional • Functions are first-class citizens • Immutability/Side Effects • Pattern matching • Type inferenceThursday, November 25, 2010
  71. 71. Pattern Matching • Pattern matching is a switch statement • Matching on properties of object graphs (not just ints) • Matching on object type • Extracting values • Compiler warning/RuntimeException on non-matchThursday, November 25, 2010
  72. 72. Pattern Matching def parseBoolean(a: Any):Boolean = { val stringTruthies = Set("true", "1", "yes") a match { case b:Boolean => b case i:Int => i == 1 case s:String => stringTruthies.contains(s) } } instanceof/cast extraction of data runtime exception if no match remember: last expression is the return statementThursday, November 25, 2010
  73. 73. Pattern Matching: Case Classes case class Town(city:String, state:String) case class Person(first:String, last:String, hometown:Town) def getTownsThatHaveSmithsInVirginia(people:List[Person]) = { people.collect { person => person match { case Person(_, "Smith", Town(town, "Virginia")) => town case _ => } } } note the _ to say “ any first name” note the embedded Town object object graph matching/ type matching/data extractionThursday, November 25, 2010
  74. 74. Case classes are great for representing your “Data objects”: • Automatically define an “extractor” for pattern matching • Automatically define equals and hashCode based on fields • Automatically define toStringThursday, November 25, 2010
  75. 75. case classes are great: copy val youngy = new Person("Youngy", "McBaby", 2, today) val youngyTwin = youngy.copy(first = "Youngina") did you notice named params?Thursday, November 25, 2010
  76. 76. Express powerful concepts concisely case class Town(city:String, state:String) case class Person(first:String, last:String, hometown:Town) Converted to Java...Thursday, November 25, 2010
  77. 77. class Person { public class Town { public static Person Person(String first, String last, Town homeTown) { public static Town Town(String city, String state) { return new Person(first, last, homeTown); return new Town(city, state); } } private final String city; private final String first; private final String state; private final String last; private final Town homeTown; public Town(String city, String state) { this.city = city; public Person(String first, String last, Town homeTown) { this.state = state; this.first = first; } this.last = last; this.homeTown = homeTown; public String getCity() { } return city; } public String getFirst() { return first; public String getState() { } return state; } public String getLast() { return last; @Override } public int hashCode() { final int prime = 31; public Town getHomeTown() { int result = 1; return homeTown; result = prime * result + ((city == null) ? 0 : city.hashCode()); } result = prime * result + ((state == null) ? 0 : state.hashCode()); return result; @Override } public int hashCode() { final int prime = 31; @Override int result = 1; public boolean equals(Object obj) { result = prime * result + ((first == null) ? 0 : first.hashCode()); if (this == obj) result = prime * result + ((homeTown == null) ? 0 : homeTown.hashCode()); return true; result = prime * result + ((last == null) ? 0 : last.hashCode()); if (obj == null) return result; return false; } if (getClass() != obj.getClass()) return false; @Override Town other = (Town) obj; public boolean equals(Object obj) { if (city == null) { if (this == obj) if (other.city != null) return true; return false; if (obj == null) } return false; else if (!city.equals(other.city)) if (getClass() != obj.getClass()) return false; return false; if (state == null) { Person other = (Person) obj; if (other.state != null) if (first == null) { return false; if (other.first != null) } return false; else if (!state.equals(other.state)) } return false; else if (!first.equals(other.first)) return true; return false; } if (homeTown == null) { if (other.homeTown != null) @Override return false; public String toString() { } return "Town [city=" + city + ", state=" + state + "]"; else if (!homeTown.equals(other.homeTown)) } return false; } if (last == null) { if (other.last != null) return false; } else if (!last.equals(other.last)) return false; return true; } @Override public String toString() { return "Person [first=" + first + ", homeTown=" + homeTown + ", last=" + last + "]"; } }Thursday, November 25, 2010
  78. 78. public class Town { public static Town Town(String city, String state) { return new Town(city, state); } private final String city; private final String state; public Town(String city, String state) { this.city = city; this.state = state; } public String getCity() { return city; } public String getState() { return state; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((city == null) ? 0 : city.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Town other = (Town) obj; if (city == null) { if (other.city != null) return false; } else if (!city.equals(other.city)) return false; if (state == null) { if (other.state != null) return false; } else if (!state.equals(other.state)) return false; return true; } @Override public String toString() { return "Town [city=" + city + ", state=" + state + "]"; } }Thursday, November 25, 2010
  79. 79. Thursday, November 25, 2010
  80. 80. Scala is functional • Functions are first-class citizens • Immutability/Side Effects • Pattern matching • Type inferenceThursday, November 25, 2010
  81. 81. Type inference • Local variables • Return type • Type parametersThursday, November 25, 2010
  82. 82. More noise reduction • Semicolons • Dots • Braces • Parenthesis • returnThursday, November 25, 2010
  83. 83. • How does type inference affect readability? reducing boilerplate is obvious win but what about inherited/old code? scala style guide recommends never inferring return typeThursday, November 25, 2010
  84. 84. Extra innings • Option • Implicit conversions • Named parameters/default valuesThursday, November 25, 2010
  85. 85. Where’s the bug? String name = getPerson("person1234").getName();Thursday, November 25, 2010
  86. 86. Where’s the bug? String name = getPerson("person1234").getName(); Null!Thursday, November 25, 2010
  87. 87. How do you know when a value is null? • Great guesser • Use a language that supports nullable tyypes • Clairvoyance • Documentation • Naming conventions • Sentinel values • Just pretend nothing will be null • Great tester • Just pretend everything might be null • AnnotationsThursday, November 25, 2010
  88. 88. How do you know when a value is null?Thursday, November 25, 2010
  89. 89. Scala’s approach: Option[T] def getPerson(id:String):Option[Person] = { if (id == "person123") { Some(new Person("Bob")) } else { None } }Thursday, November 25, 2010
  90. 90. Scala’s approach: Option[T] • Option is extended by Some and None • Encodes optional values into your API with zero magic - can be used in Java • Scala’s type inference keeps the noise to a minimum • May seem like an extra burden, but the burden is already there once you have optional valuesThursday, November 25, 2010
  91. 91. Scala’s approach: Option[T] //previous approach: doesnt compile! val name = getPerson("person123").name //.get will throw a RuntimeException if it is null here val name2 = getPerson("person123").get.name //get the value, or use a default val name3 = getPerson("person123").getOrElse("Name unknown") //in some cases (not this one), pattern matching is nice val name4 = getPerson("person123") match { case Some(name) => name case None => "Name Unknown" }Thursday, November 25, 2010
  92. 92. Implicit conversions • Automatically convert types • Commonly used to add behavior to existing closed source classes • Programmer controls the scope of the conversions - not global • Goes beyond just adding methodsThursday, November 25, 2010
  93. 93. Implicit Conversions A Rich Wrapper class RichInt(i:Int) { def times(f: => Unit) = { for (x <- 0 to i) f } } new RichInt(5).times { println("hey!") } yuckThursday, November 25, 2010
  94. 94. Implicit Conversions class RichInt(i:Int) { def times(f: => Unit) = { for (x <- 0 to i) f } } implicit def intToRichInt(i:Int) = new RichInt(i) 5 times println("hey!")Thursday, November 25, 2010
  95. 95. Named and default parameters def sendEmail( to : List[String], from : String, subject : String = "No subject", cc : List[String] = Nil, bcc : List[String] = Nil, attachments : List[File] = Nil )Thursday, November 25, 2010
  96. 96. Named and default parameters sendEmail(List("a@a.com"), "b@b.com") sendEmail(to = List("a@a.com"), from = "b@b.com", subject ="Status Check!") sendEmail(to = List("a@a.com"), from = "b@b.com", subject ="Status Check!", attachments = List(new File("coolpic.jpg")))Thursday, November 25, 2010
  97. 97. Out of time • DSLs • Currying • Sane generics (no wildcards!) • Non-alpha method names • Multi-line strings • Structural typing • XML LiteralsThursday, November 25, 2010
  98. 98. My top10 Aspects of Scala • Java Interop • rich collections library • Concise/Type inference • default/named params • Functions-as-objects • case classes • Some/None/Option • REPL • implicit conversions • traitsThursday, November 25, 2010
  99. 99. These concepts are in other statically typed JVM languages too! • Fantom (from Richmond!) • Gosu • Java 8 (currently “late 2012”)Thursday, November 25, 2010
  100. 100. Go try it! • http://scala-lang.org • http://www.simplyscala.com/ - try simple samples without installing • I will be posting slides + a pre-built Eclipse with this talks code on my blog.Thursday, November 25, 2010
  101. 101. Thanks! adamrabung@gmail.com http://squirrelsewer.blogspot.com twitter:squirrelsewerThursday, November 25, 2010

×