Ponies and Unicorns With Scala

844 views
745 views

Published on

A teaser talk for Scala newbies, introducing five basic elements that (in my opinion) make the transition from Java to Scala a no-brainer.

Given at the 7th JJTV (Israeli Java/JVM user group) tool night, July 2nd, 2013.

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

No Downloads
Views
Total views
844
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Ponies and Unicorns With Scala

  1. 1. Ponies and unicorns with A JJTV Tools Night Presentation Tomer Gabel, Wix.com
  2. 2. You want these • Type inference • Closures • Options • Traits • Collection Framework
  3. 3. Type Inference #1
  4. 4. Saves buttloads of code! final Map<String, String> parameters = new HashMap<String, String>(); parameters.put( “param1”, “value” ); parameters.put( “param2”, “value” ); val parameterMap = Map( “param1” → “value”, “param2” → “value” )
  5. 5. Type inference • Pervasive! – Locals – Parameters – Type parameters – … everything other than formal definitions, really!
  6. 6. Closures #2
  7. 7. Simply put… • Short-hand for unnamed functions val isEven = ( v: Int ) => v % 2 == 0 • Can be passed around as parameters def filterBy( predicate: Int => Boolean )
  8. 8. Functional building block • All Scala collections (of T) support: – Filtering by predicate (T=>Boolean) – Finding a value by predicate – Mapping by transformation (T=>R) – Sorting by an arbitrary function
  9. 9. Compare… List<Integer> list = …; List<Integer> onlyEvens = filter( list, new Predicate<Integer>() { public boolean test( Integer value ) { return value % 2 == 0; } } ); val list: List[ Int ] = …; val onlyEvens = list.filter( _ % 2 == 0 )
  10. 10. Callbacks // Runs a background process def invokeProcess( command: String, onExit: Int => Unit ) // Call site: invokeProcess( “tar –cvjf backup.tar.bz2 *”, exitCode => if ( exitCode <> 0 ) error( “Failed to generate backup!” ) )
  11. 11. Options #3
  12. 12. NPEs are crap String lower( String v ) { if ( v == null ) return null; else return v.toLowerCase(); } Does not document intent Redundant Always needs checking
  13. 13. NPEs are still crap • In Scala, nulls are a code smell • … except for legacy interop def lower( v: Option[ String ] ) = v.map( _.toLowerCase ) Clear semantics Explicit access
  14. 14. Options are great! • Loads of helpers: – optional.getOrElse( “default value” ) – optional.orElse( anotherOption ) – optional.orNull // Legacy helper • Just another collection! – def lookup( id: Long ): Option[ User ] = … for ( id <- idList; user <- lookup( id ) ) println( user.name )
  15. 15. Traits #4
  16. 16. Multiple inheritance • Traits are like Java interfaces • … with optional implementation • Useful for: – Helpers – Functional composition – Good old interface declarations
  17. 17. Boilerplate 101 import org.slf4j.Logger; import org.slf4j.LoggerFactory; class MyClass { private static Logger log = LoggerFactory.getLogger( MyClass.class ); void myMethod() { log.info( “Some message” ); } } x1000 classes Boilerplate!
  18. 18. The Logging trait import org.slf4j.LoggerFactory trait Logging { private val log = LoggerFactory.getLogger( this.getClass ); def info( s: => String ) { if( log.isInfoEnabled ) log.info( s ); } def trace( s: => String ) { … } // etc. }
  19. 19. A better way • Now you can do.. class MyClass extends Logging { def myMethod() { … info( “Some message” ) } }
  20. 20. Functional composition • Consider collections… – Iterable[T] provides iteration – Seq[T] implies ordering and indexing – Vector[T] implements Seq[T] • map, filter, foreach implemented by Iterable[T] • … Seq adds indexOf, slice, sortBy… • … Vector re-implements for performance!
  21. 21. Collection Framework #5
  22. 22. It will rock your world Given the following: case class Person( name: String, age: Int ) val people: List[ Person ] = … You can now do… val firstTen = people.take( 10 ) val onlyMinors = people.filter( _.age < 18 ) val nameSet = people.map( _.name ).toSet
  23. 23. … and then some That was just the tip of the iceberg. val sorted = people.sortBy( _.age ) val index = people.groupBy( _.name.head ) val pairs = people.sliding( 2, 2 ) val ( minors, adults ) = people.partition( _.age < 18 )
  24. 24. Maps • Maps are also collections • … and can be used as lookup functions val peopleById: Map[ Long, Person ] = … def getPeople( ids: List[ Long ] ) = ids map peopleById
  25. 25. Over and out • Thank you for your time! • Questions and comments welcome! – tomer@tomergabel.com – http://www.tomergabel.com

×