‣ A language for the JVM ‣ Statically typed ‣ Compiles to JVM bytecode, just like Java ‣ Research on compiling to other platforms ‣ The JVM has influenced Scala’s semantics ‣ Language + compiler + standard library
‣ Supports two programming paradigms ‣ Object-Oriented Programming (OOP) ‣ Functional Programming (FP) ‣ Created to explore this mix ‣ Martin Odersky sees FP and OOP as orthogonal ‣ OOP does not imply imperative
‣ Various opinions ‣ All centered around the same concept ‣ FP is programming w/ functions/values ‣ FP is programming w/o side-effects/mutations ‣ FP’s roots are in mathematical functions ‣ A function’s output is determined entirely by its input
Improves support for OOP ‣ Good support for FP ‣ Runs on JVM, one of the best VMs around ‣ A better Java ‣ Yet interoperable with Java ‣ Powerful type system (vs. Clojure) ‣ Favours immutability, but allows mutability
String, age: Int) { def bio: String = s"$name is a $age years old developer." } val person = new Person("Ionuț", 28) person.bio // Ionuț is a 28 years old developer.
Person(name: String, age: Int) { def bio: String = s"$name is a $age years old developer." } object Person { def apply(name: String, age: Int) = { new Person(name, age) } } val person = Person("Ionuț", 28)
Person(val name: String, val age: Int) { def bio: String = s"$name is a $age years old developer." } object Person { def apply(name: String, age: Int) = { new Person(name, age) } } val person = Person("Ionuț", 28)
class City(name: String, country: String) case class Address(street: String, number: String, city: City) case class Person(name: String, age: Int, address: Address) val p = Person( name = "Ionuț", age = 28, address = Address( number = "42", street = "Endless", city = City("Bucharest", "Romania") ) ) p match { case Person(name, _, Address(_, _, City(city, _))) => s"$name lives in $city." }
val user: Option[User] = Users.find(id) user match { case Some(user) => OK(render(user)) case None => NotFound() } // or using higher-order functions user.map(u => OK(render(u))).getOrElse { NotFound() }
{ def foo: String = "foo" } trait Bar { def bar: Int = 42 } class Baz extends Foo with Bar val baz = new Baz print(baz.foo) // "foo" print(baz.bar) // 42