introduction to scala

20
Introduction to Scala by Michel Perez www.mrkaspa.com

Upload: michel-perez

Post on 15-Apr-2017

126 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Introduction to scala

Introduction to Scala

by Michel Perez www.mrkaspa.com

Page 2: Introduction to scala

Good Parts

2

JVM & JAVA INTEROPERABILITY STATICALLY TYPED

TYPE INFERENCE REPL

EXPLICIT MUTABILITY NO SEMICOLON

EVERYTHING IS AN OBJECT MIXINS

Page 3: Introduction to scala

Bad Parts

3

IDE JARS & MAVEN

LEARNING GURVE COMPILE TIME

Page 4: Introduction to scala

Object Oriented Programming

CLASSES OBJECTS

VISIBILITY INTERFACES

ABSTRACT CLASS INHERITANCE

Page 5: Introduction to scala

Scala Variables & Values

5

val labels = Set(“")val labels = Set[String](“”)

var labels = Set[String](“”)

Mutables

Inmutables

Type Inference

Page 6: Introduction to scala

Visibility

6

Public by default

Instance private to the current instanceval Num = 1private[this] val Num = 1private val Num = 1private[package] val Num = 1protected val Num = 1

Instance private to the class

Instance private to a custom package

Instance protected to its children

Page 7: Introduction to scala

Classes

7

Case class -> get, set, constructor auto

Traits -> Interfaces + Mixins

Generic clases/traits

Singleton Object

case class SocialNetwork(id: String, name: String)

trait LinkedList[+A] { def isEmpty: Boolean def head: A def tail: LinkedList[A] def at(index: Int): A def prepend[B >: A](elem: B): LinkedList[B] =

new Cons(elem, this)

}

object Nil extends LinkedList[Nothing] {

class Cons[A](val head: A, val tail: LinkedList[A]) extends LinkedList[A] {

Page 8: Introduction to scala

Mixins

8

Typesafe

Multiple inheritance

trait NeoTest extends FunSpec with MustMatchers with BeforeAndAfterAll with BeforeAndAfterEach { }

trait HelperTest { this: NeoTest =>}

class NodeSpec extends NeoTest with HelperTest {}

Used for composition

Page 9: Introduction to scala

Abstract class

9

Java compatibilityabstract class Rel[A, B] { val from: A val to: B }

case class MyRel(from: MyUser, to: MyUser, enabled: Boolean) extends Rel[MyUser, MyUser]

Can not be instantiated

Can have a constructor

Relation is-a

Page 10: Introduction to scala

Functional Programming

FUNCTIONS AS FIRST CITIZENS IMMUTABILITY

CURRYING CLOSURES

LAZY EVALUATION PATTERN MATCHING

TYPE CLASS ALGEBRAIC DATATYPES

Page 11: Introduction to scala

Scala Functions

11

Every function must have a return type

Functions as parameters

You can return functions

Vector.fill(queens.length)("* “).updated(col, "X ").mkString

def lambda = (x: Int) => x + 1

val multiplier = (i:Int) => i * 10

def sumComp(a: Int): (Int) => Int = { def sum(b: Int) = a + b }

val fun = sumComp(5) fun(1)

def sumComp(a: Int)(b: Int): Int = { a + b }

Currying

Page 12: Introduction to scala

Pattern Matching

12

Like a super switchval secondElement = List(1,2,3) match { case x :: y :: xs => y case _ => 0 }

val foodItem = "porridge" def goldilocks(expr: Any) = expr match { case (`foodItem`, _) => "eating" case ("chair", "Mama") => "sitting" case ("bed", "Baby") => "sleeping" case _ => "what?" } goldilocks(("porridge", "Papa"))

Compare & extract

Page 13: Introduction to scala

Implicits

13

Inject parameters to a method

Automatic conversation

implicit def implChange(str:String):Int = new Integer(str) def sum(a:Int, b:Int):Int = a +b sum("1", 2)

def save[T](t: T)(implicit connection: Neo4jREST, ec: ExecutionContext):

Page 14: Introduction to scala

Monads

14

map, flatMap, filter

for comprehension

def readAsync(): Future[Option[List[String]]] = Future { readFile() }def readFile(): Option[List[String]] = Try { Source.fromURL("/tmp/file.txt").getLines().toList } toOptionval futSize: Future[Int] = for { result <- readAsync() list <- result } yield list.sizeval futSizeMap: Future[Option[Int]] = readAsync().map { result: Option[List[String]] => result.map((list: List[String]) => list.size) }

Future, Option, Try, Either

Page 15: Introduction to scala

Type Class Pattern

15

AKA context bound

implicit val myUserMapper = Mapper.build[MyUser]

abstract class NeoNode[T: Mapper] extends Labelable { val MapperT = implicitly[Mapper[T]]def save(t: T)(implicit connection: Neo4jREST, ec: ExecutionContext): Future[Boolean] = Future {}object ToOps{ implicit def operations(t: T) = NeoNodeOperations(t) }case class NeoNodeOperations(t: T) { def save()(implicit connection: Neo4jREST, ec: ExecutionContext) =

NeoNode.this.save(t)}

}

case class MyUser(id: String, name: String, age: Int)implicit val userNode = NeoNode("user", (user: MyUser) => user.id)import graph.model.orm.UserNodes.userNode.ToOps._val node1 = MyUser("1", "Michel Perez", 27)node1.save()

Mix traits - abstract class & implicit

Page 16: Introduction to scala

Good Ecosystem

AKKA PLAY FRAMEWORK

SPARK SBT

SCALOID SCALAJS

ORMS TYPELEVEL

SCALAJSFINAGLE

Page 17: Introduction to scala

Actors

17

Lightweight threads

Event oriented

class BloodRequester extends Actor { implicit val executor = context.dispatcher override def receive: Receive = { case BloodRequest(request) => DonorDAO.findNear(request).map { donors => donors.foreach { donor => facebookNotifier ! FacebookNotify(donor, request) } } } }

Restart in failures

Supervision

Page 18: Introduction to scala

ScalaTest

18

Test Unit

trait NeoTest extends FunSpec with MustMatchers with BeforeAndAfterAll with BeforeAndAfterEach {override def beforeEach(): Unit = { NeoDBCleaner.cleanDB() }describe("UserDAOs") { it("creates an user an checks the default group") { withUser { (user, saved) => saved must be(true) val query = s"""match (a:user {id: "${user.id.getOrElse("")}"})-[c:has_group]->(b:group) return a, b, c""" val result = Await.result(NeoQuery.executeQuery[UserLogin, Group, HasGroupLogin](query), 2 seconds) result.length must be(1) } }}

Multiple Paradigms

TDD

BDD

Page 19: Introduction to scala

ScalaZ

19

Inspired in Haskell

case class Box[A](itemType: A)

implicit val machFunctor = new Functor[Box] { override def map[A, B](fa: Box[A])(f: (A) => B): Box[B] = { val b = f(fa.itemType) Box(b) } }

import machFunctor.functorSyntax._

val boxInt = Box(1)

val boxString = boxInt map { x => s"$x..." }

More functional

Page 20: Introduction to scala

Scala wants U ;)

20

https://www.coursera.org/course/progfun

http://scala-exercises.47deg.com/koans