Scala


Best of all worlds

Who am I?

Why Scala?

  • Everyone likes JVM (JRuby, Jython, Kotlin, Groovy)
  • Huge Java ecosystem
  • Nice blend of OOP & FP
  • Statically typed yet concise and expressive
  • Traits, pattern matching, implicits, macros
  • Concurrent/distributed programming: futures, actors, Spark
  • Multiplatform: ScalaJS, ScalaNative, Scaloid
  • Scala is one of 2 highest paid p.l. (Big data & ML)
  • It's cool to hate Java ^_^

Why Scala?

  • tools: Play, Spark, Kafka, Akka, Gatling
  • apps: GitBucket, Graphcool, DBpedia, Lichess
  • companies: Twitter, Netflix, Linkedin, Verizon, Zalando, Coursera, Duolingo, Apple...

James Gosling about Scala

OOP done right

  • Everything is an object
  • No operators, just methods
  • Syntax sugar
  • Expression oriented
  • Powerful type system


							// mutable value/reference
							var variable = ...

							// immutable value/reference aka constant
							// calculated only ONCE
							val value = ...

							// method
							def method(p: Type) = ??? // TODO

							// ~constant
							lazy val cached = ...
					

							// type inference
							val num: Int = 5
							val num = 5
							5.toString()  // or "5.toString" or "5 toString"

							// "operators"
							1 + 2
							1.+(2)

							// no ternary operator
							// yup? "Yep": "Nope"
							val isIt2 = if(yup) "Yep" else "Nope"

							// first? "Yep": (second? "Nope": "Maybe")
							val isIt4 = if(first) "Yep" else if(second) "Nope" else "Maybe"
					

Boilerplate-free classes


                                class MyClass1

                                class MyClass2(x: Int)                  // constructor

                                class MyClass3(val x: Int, var y: Int)  // fields

                                class MyClass4(x: Int, y: Int = 3) {
                                  def aMethod = x + y                   // method
                                }

                                new MyClass4(1, 2)      // regular
                                new MyClass4(5)         // using default params
                                new MyClass4(y=7, x=3)  // named params

                                // multiple classes per file, generics, traits, abstract types ...
						

Singleton objects
(and companions/friends)

no static "methods"

                                    object StringUtils {
                                      def trim(str: String): String = ...
                                    }
                        

                                // static factory methods
                                object MyClass {
                                  def apply(param1: String) = new MyClass(param1)
                                }
                                val mc1 = new MyClass("ABC")    // can't change to subclass later
                                val mc2 = MyClass("DEF")        // desugars to MyClass.apply

                                val fruits = List("apple", "orange")
                    

Implicit conversion

monkey patching / C# extension methods

                                  implicit class StringOps(str: String) {
                                    def firstCaps: String = {
                                      if (str.isEmpty) str
                                      else str(0).toUpper + str.drop(1)
                                    }
                                  }

                                  println("whatever".firstCaps) // Whatever
                    

Structural types (shape)

If it walks like a duck and it quacks like a duck,

it might be a turkey wrapped in a duck adapter.


                              def doQuack(quackable: { def quack: String }) =
                                println(quackable.quack)
                              
                              class Duck {
                                def quack: String = "Quack, quack!"
                              }

                              doQuack(new Duck) // Quack, quack!
                              
                              // type Ducky = { def quack: String }
                              // def doQuack(quackable: Ducky) =
					

Uniform access principle

I don't care if it is a field or a method! Same code. :)


                            class Person {
                              var age = 0
                            }

                            // same as:

                            class Person {
                              private var privateAge = 0

                              def age = privateAge // getter

                              def age_=(newValue: Int) { // setter
                                if (newValue > privateAge) privateAge = newValue
                              }
                            }
                    

FP

  • Immutability, lazy vals, by-name params
  • Functions are values/objects
  • Generics
  • Currying
  • For comprehensions (map, flatMap, foreach)
  • Pattern matching, ADTs


                                val nums = List(1, 2, 3)

                                val numsPlus1 = nums.map ( x => x + 1 )

                                val numsPlus2 = nums.map { x => x + 2 }

                                val numsPlus3 = nums.map (_ + 3)

                                val plus4 = (x: Int) => x + 4
                                val numsPlus4 = nums.map(plus4)

                                val numsPlus5 = for (x <- nums) yield x + 5
                        

                            // functional - declarative
                            val sum = nums.foldLeft(0) { (acc, x) =>
                                acc + x
                            }

                            // imperative - boring, error prone
                            int sum = 0;
                            for (int i = 0; i < nums.length; i++) {
                                sum += nums[i];
                            }
                    

                                // ADT (Algebraic Data Types)
                                sealed trait Animal { def name: String }
                                case class Cat(name: String) extends Animal
                                case class Dog(name: String, weight: Int) extends Animal

                                val pet: Animal = Dog("Fido", 7)
                                val petStatement = pet match {
                                  case Cat(name)                         => s"$name says meow!"
                                  case Dog(name, weight) if (weight < 2) => s"$name says yip!"
                                  case Dog(name, weight)                 => s"$name says bark!"
                                }
                                println(petStatement)
                            

Implicit parameters

typeclasses, Haskell anyone?

                            def myMethod(x: Int, ctx: AlwaysPresentContext) ...
                            myMethod(1, ctx)
                            myMethod(2, ctx) ...

                            // much better :)
                            def myMethod(x: Int)(implicit ctx: AlwaysPresentContext)
                            implicit val ctx = new AlwaysPresentContext
                            myMethod(1)
                            myMethod(2)
                        

Macros

Transform and generate code at compile time.

Similar, but far more powerful than Java/C# annotations

quill

Resources

That's all folks!


Questions?

Scala programmer waits for project to build

waiting-for-the-build

INFOBIRO.ba

(Bosanski internet resursni centar)

  • Scala
  • Akka
  • Elasticsearch
  • Stanford NLP
  • Postgres

LDS

  • Scala
  • Play Framework
  • Slick
  • Elasticsearch
  • MySql/MongoDB