Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala Thursday

Scala Thursday

weekly dose of scala

Oren Mizrahi

April 10, 2017
Tweet

Other Decks in Programming

Transcript

  1. THE “WH(Y/TF)” OF SCALA • Scala is different (def, Object

    etc) • Scala is opinionated (For comps, Unit, Option) • Scala is “Magic” (apply, smart: set vs class) • Why? • Because it tries to push us in the right direction • Functional Programming
  2. SCALA VS JAVA it is intentional public class JavaClass {

    public JavaClass() { this(null); } public JavaClass(Resource r) { this(r, null); } public JavaClass(R r1, R r2) { … } } class ScalaClass(r1: R, r2: R) { def this(r: R) = this(r, null) def this() = this(null) }
  3. FUNCTIONAL PROGRAMMING • Pure functions • Higher order functions •

    Curry • Declarative rather than imperative • Function composition
  4. FOR COMPREHENSION var state = "" for (a <- 1

    to 10) { state = state + a if (a < 10) state = state + "," } println(state) PART 1
  5. FOR COMPREHENSION one more var result = List[Int]() for (n

    <- 1 to 10) { result = result :+ (n * n) } println(result) PART 2
  6. FOR COMPREHENSION finally! • Did it feel familiar ? val

    result = (1 to 10).map(n => n * n) • Easy on the eyes • Learn one, use everywhere flatMap,filter etc • Opens the power of Chaining PART 4
  7. FOR COMPREHENSION getting jiggy with it! • Two iterators -

    no problem val result= for (i <- List(1,2,3); j <- List(4,5,6)) yield (i,j) println(result) // List((1,4), (1,5), (1,6), (2,4), (2,5), (2,6), (3,4), (3,5), (3,6)) PART 5
  8. FOR COMPREHENSION getting jiggy with it! • Two iterators plus

    constraints - no problem val result= for (i <- List(1,2,3) if i % 2 != 0; j <- List(4,5,6) if j % 2 == 0) yield(i,j) println(result) // List((1,4), (1,6), (3,4), (3,6)) PART 6
  9. FOR COMPREHENSION a better way • Scala wants you do

    something else... val result = List(1,2,3).filter(n=>n%2!=0).Map(n=> List(4,5,6).filter(m=>m%2==0).map(m=> (n,m))) println(result) // List((1,4), (1,6), (3,4), (3,6)) PART 7
  10. FOR COMPREHENSION conclusion • It’s good.use it! • One step

    deep into functional writing • Easy to “comprehend” it as opposed to for big blocks • Keep your bugs contained in the transformations • Easier to test - data goes through the pipeline PART 8
  11. OPTIONS cause it always nice to have “some” sealed abstract

    classOption[+A] extends Product with Serializable • WHY? NULL was a bad idea & error prone • Scala solution of how to represent “maybe” (something or nothing) • Represents optional values. Instances of Option are either an instance of scala.Some or the object None. final case classSome[+A](value: A) extends Option[A] with Product with Serializable Object None extends Option[Nothing] with Product with Serializable • Not to be confused with Nothing: abstract final classNothing extends Any PART 1
  12. OPTIONS by example case class StorageProvider(name:String, scope: Option[String] ,saveRate:Int )

    { def this(name:String, scope: String, saveRate:Int) = this(name, Some(scope), saveRate) def this(name:String, saveRate:Int) = this(name, None, saveRate) } val sp1 = new StorageProvider("LocalStorage", "cart", 1000); val sp2 = new StorageProvider("LocalStorage", 1000); PART 2
  13. OPTIONS in the real world... def str2Int(s: String): Option[Int] =

    { try { Some(Integer.parseInt(s.trim)) } catch { case e: Exception => None } } val x = str2Int("1") // Option[Int] = Some(1) val x = str2Int("one") // Option[Int] = None PART 4
  14. OPTIONS in the real world... case class Account(sid: Int, company:

    String, worth: Int) { def doSomething(): Unit = { println("something"); } } object AccountRepository { private val accounts = Map(123 -> Account(123, "HSBC", 5), 456 -> Account(123, "POALIM", 1)) def findBySid(id: Int): Option[Account] = accounts.get(id)} PART 5
  15. OPTIONS in the real world... val accountValid = AccountRepository.findBySid(123) //

    Some(Account(123,HSBC,5))accountValid.isDefined // true accountValid.isEmpty // false accountValid.map(x=>x.doSomething()) // something val accountInvalid = AccountRepository.findBySid(0) // Option[Account] = None accountInvalid.isDefined // false accountInvalid.isEmpty // true accountInvalid.map(x=>x.doSomething()) // None PART 6
  16. RANGES (scala.collection.immutable) sealed class Range extends AbstractSeq[Int] with IndexedSeq[Int] with

    CustomParallelizable[Int, ParRange] with Serializable • new Range(start: Int, end: Int, step: Int) 1 to 5 // scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5) 1 until 5 // scala.collection.immutable.Range = Range(1, 2, 3, 4) PART 1
  17. RANGES (scala.collection.immutable) 1 to 5 by 2 // scala.collection.immutable.Range =

    Range(1, 3, 5) 'a' to 'c' // scala.collection.immutable.NumericRange.Inclusive[Char] = NumericRange(a, b, c) (1 to 5).toList [toArray, toSet, toWhatever] // List(1, 2, 3, 4, 5) PART 2
  18. RANGES (scala.collection.immutable) List.range(1, 10) // List[Int] = List(1, 2, 3,

    4) List.range(0, 5, 2) // List[Int] = List(0, 2, 4) for (n <- 1 to 100 by 10) yield n // scala.collection.immutable.IndexedSeq[Int] = Vector(1, 11, 21, 31, 41, 51, 61, 71, 81, 91) PART 3
  19. RANGES conclusions - They describe series of numbers. - This

    makes calling functions on sequences easier and more intuitive. - They can very helpful: val m = t match { case x if 0 until 10 contains x => true case _ => false } PART 4