Slide 1

Slide 1 text

for Scala C# Developers Developers

Slide 2

Slide 2 text

1. you know how to computer 2. different syntax isn't taxing 3. you’ll bug me afterwards preconditions

Slide 3

Slide 3 text

why would a C# developer want to learn Scala?

Slide 4

Slide 4 text

1. curiosity 2. necessity

Slide 5

Slide 5 text

Curiosity allows developers to discover new ways of doing things and broaden their ability 1. curiosity 2. necessity

Slide 6

Slide 6 text

As the technological landscape grows niche skills and specialisms become less important 1. curiosity 2. necessity

Slide 7

Slide 7 text

but why scala? clojure f# java kotlin elixir ruby go haskell … why not ___ or one of the other ~794 languages* * excluding BASIC dialects & esoteric languages [WIKIPEDIA]

Slide 8

Slide 8 text

1. i don’t know 2. ½ way up the learning curve 3. trends in industry 4. data science

Slide 9

Slide 9 text

so, scala…

Slide 10

Slide 10 text

java/.net martin odersky epfl 2004(ish) typesafe v 2.10.3

Slide 11

Slide 11 text

functional statically typed object oriented type inference interop immutable by default concurrency baked in

Slide 12

Slide 12 text

compile times complexity esoteric mixing paradigms

Slide 13

Slide 13 text

syntax teardown

Slide 14

Slide 14 text

public class Hello1 { public static void Main() { string message = “Hello World”; System.Console.WriteLine(message); } } HelloWorld.cs

Slide 15

Slide 15 text

object HelloWorld extends App { val message = “Hello World” println(message) } HelloWorld.scala

Slide 16

Slide 16 text

object HelloWorld { def main(args: Array[String]): Unit = { val message: String = “Hello World” println(message) } } HelloWorld.scala

Slide 17

Slide 17 text

object HelloWorld { def main(args: Array[String]): Unit = { val message: String = “Hello World” println(message) } } HelloWorld.scala object def = : Unit :String no semicolons

Slide 18

Slide 18 text

class Person { private readonly string _name; public string name { get { return _name; } } public int age { get; set; } ! public Person(string name, int age) { this._name = name this.age = age } } Person.cs

Slide 19

Slide 19 text

class Person(val name: String, var age: Int) Person.scala

Slide 20

Slide 20 text

class Person(val name: String, var age: Int) Person.scala val name: String, var age: Int

Slide 21

Slide 21 text

class Person(val name: String, var age: Int) Person.scala val var

Slide 22

Slide 22 text

language features

Slide 23

Slide 23 text

default values for functions options vs nulls

Slide 24

Slide 24 text

def sayHello(name: String = "World") { println("Hello, " + name) } ! def sayHello(name: String = null) { println("Hello," + if(name == null) "" else "World") } ! def sayHello(name: Option[String] = None) { println("Hello," + name.getOrElse("World")) }

Slide 25

Slide 25 text

def sayHello(name: String = "World") { println("Hello, " + name) } ! def sayHello(name: String = null) { println("Hello," + if(name == null) "" else "World") } ! def sayHello(name: Option[String] = None) { println("Hello," + name.getOrElse("World")) } name: String = “World” if(name == null) "" else "World" Option[String] None name.getOrElse("World")

Slide 26

Slide 26 text

collection support lambdas and shorthand for comprehension

Slide 27

Slide 27 text

List(1,2,3,4) .map(number => number + 1) .filter(_ % 2 == 0) .foldLeft(0)(_ + _)

Slide 28

Slide 28 text

List(1,2,3,4) .map(number => number + 1) .filter(_ % 2 == 0) .foldLeft(0)(_ + _) List(1,2,3,4) number => number + 1 _ % 2 == 0 (0)(_ + _)

Slide 29

Slide 29 text

List(1,2,3,4) .map(number => number + 1) .filter(_ % 2 == 0) .foldLeft(0)(_ + _) (1 :: 2 :: 3 :: 4 :: Nil)

Slide 30

Slide 30 text

Map( “name" -> "James Hughes”, “handle" -> "@kouphax" )

Slide 31

Slide 31 text

Map( “name" -> "James Hughes”, “handle" -> "@kouphax" ) “name" -> "James Hughes”

Slide 32

Slide 32 text

val attendees = List( Person("james", List("scala", ".net")), Person("will", List("java", ".net")), Person("luke", List("ios", "drinking redbull")) ) val coolPeople = for { attendee <- attendees if attendee.name.startsWith(“j"); skills <- attendee.skills if skills.contains("scala") } yield attendee.name

Slide 33

Slide 33 text

val attendees = List( Person("james", List("scala", ".net")), Person("will", List("java", ".net")), Person("luke", List("ios", "drinking redbull")) ) val coolPeople = for { attendee <- attendees if attendee.name.startsWith(“j"); skills <- attendee.skills if skills.contains("scala") } yield attendee.name for yield

Slide 34

Slide 34 text

traits dynamic composition

Slide 35

Slide 35 text

trait Logging { def log(message: String) = println(message) } ! class Worker extends TheHadoops with Logging { def onFinish = { log("Finished working") } } ! trait BetterLogging extends Logging { override def log(message: String) = println("[INFO] " + message) }

Slide 36

Slide 36 text

trait Logging { def log(message: String) = println(message) } ! class Worker extends TheHadoops with Logging { def onFinish = { log("Finished working") } } ! trait BetterLogging extends Logging { override def log(message: String) = println("[INFO] " + message) } trait Logging extends TheHadoops with Logging trait BetterLogging extends Logging override

Slide 37

Slide 37 text

val worker = new Worker val betterWorker = new Worker with BetterLogging ! worker.work > Finished Working ! betterWorker.work > [INFO] Finished Working

Slide 38

Slide 38 text

val worker = new Worker val betterWorker = new Worker with BetterLogging ! worker.work > Finished Working ! betterWorker.work > [INFO] Finished Working with BetterLogging

Slide 39

Slide 39 text

pattern matching case classes and extraction

Slide 40

Slide 40 text

def wordify(number: Int) = { number match { case 1 => "One" case 2 => "Two" case n if n > 100 => "More than one hundred" case _ => "Between two and one hundred" } }

Slide 41

Slide 41 text

def wordify(number: Int) = { number match { case 1 => "One" case 2 => "Two" case n if n > 100 => "More than one hundred" case _ => "Between two and one hundred" } } match case 1 => "One" case n if n > 100 => "More than one hundred" case _ => "Between two and one hundred"

Slide 42

Slide 42 text

def length(list: List[_]) : Int = { list match { case Nil => 0 case _ :: tail => 1 + length(tail) } }

Slide 43

Slide 43 text

def length(list: List[_]) : Int = { list match { case Nil => 0 case _ :: tail => 1 + length(tail) } } Nil _ :: tail

Slide 44

Slide 44 text

trait Role case class Anon() extends Role case class User(val name: String, admin: Boolean) extends Role ! def isAdmin(user: Role) = { user match { case Anon() => println("anons aren't admins”); false case User(name, true) => println(name + " is admin”); true case User(name, false) => println(name + " is not an admin”); false } }

Slide 45

Slide 45 text

trait Role case class Anon() extends Role case class User(val name: String, admin: Boolean) extends Role ! def isAdmin(user: Role) = { user match { case Anon() => println("anons aren't admins”); false case User(name, true) => println(name + " is admin”); true case User(name, false) => println(name + " is not an admin”); false } } Anon() User(name, true) User(name, false)

Slide 46

Slide 46 text

implicits as extension methods implicit scope implicit type conversions

Slide 47

Slide 47 text

implicit class FancyString(val s: String) { def makeChristmasy = "***" + s + "***" } ! "CHRISTMAS".makeChristmasy

Slide 48

Slide 48 text

implicit class FancyString(val s: String) { def makeChristmasy = "***" + s + "***" } ! "CHRISTMAS".makeChristmasy implicit makeChristmasy

Slide 49

Slide 49 text

trait Logger { def log(s: String) } ! class LoggerImpl extends Logger { def log(s: String) = println(s) } ! def inspect(s: String)(implicit logger: Logger) { logger.log(s) } ! implicit val defaultLogger = new LoggerImpl ! inspect("Hello")

Slide 50

Slide 50 text

trait Logger { def log(s: String) } ! class LoggerImpl extends Logger { def log(s: String) = println(s) } ! def inspect(s: String)(implicit logger: Logger) { logger.log(s) } ! implicit val defaultLogger = new LoggerImpl ! inspect("Hello") trait Logger LoggerImpl extends Logger implicit logger: Logger implicit

Slide 51

Slide 51 text

def log(s: String) = { println(s) } ! log(1) // Type error ! implicit def int2String(i: Int): String = i.toString ! log(1) // success

Slide 52

Slide 52 text

def log(s: String) = { println(s) } ! log(1) // Type error ! implicit def int2String(i: Int): String = i.toString ! log(1) // success log(s: String) // Type error implicit def // success

Slide 53

Slide 53 text

string interpolation string context multiline strings

Slide 54

Slide 54 text

val plain = """ This is a multiline string """ ! val stripped = """ | This is a | multiline string """.stripMargin

Slide 55

Slide 55 text

val plain = """ This is a multiline string """ ! val stripped = """ | This is a | multiline string """.stripMargin “”” “”” | | stripMargin

Slide 56

Slide 56 text

def sayHi(name: String) { println(s"Hi $name") } sayHi("james")

Slide 57

Slide 57 text

def sayHi(name: String) { println(s"Hi $name") } sayHi("james") s”Hi $name”

Slide 58

Slide 58 text

implicit class SQLHelper(val sc: StringContext) extends AnyVal { def sql(args: Any*): PreparedStatement = { SQLEngine.prepare(sc.s(args)) } } ! val id = 1 ! val query = sql"select * from users where id = $id"

Slide 59

Slide 59 text

implicit class SQLHelper(val sc: StringContext) extends AnyVal { def sql(args: Any*): PreparedStatement = { SQLEngine.prepare(sc.s(args)) } } ! val id = 1 ! val query = sql"select * from users where id = $id" implicit StringContext sql sql"select * from users where id = $id"

Slide 60

Slide 60 text

inline XML

Slide 61

Slide 61 text

def get("/:name") { ! contentType="text/html" ! Test

Hello { request.param("name") }

}

Slide 62

Slide 62 text

def get("/:name") { ! contentType="text/html" ! Test

Hello { request.param("name") }

} { request.param("name") }

Slide 63

Slide 63 text

duck typing dynamic

Slide 64

Slide 64 text

class Logger1 { def log(s: String) = println(s) } class Logger2 { def log(s: String) = println(s) } ! def log(s: String, l: { def log(s: String) }) { l.log(s) } ! log("same", new Logger1) log("same", new Logger2)

Slide 65

Slide 65 text

class Logger1 { def log(s: String) = println(s) } class Logger2 { def log(s: String) = println(s) } ! def log(s: String, l: { def log(s: String) }) { l.log(s) } ! log("same", new Logger1) log("same", new Logger2) l: { def log(s: String) }

Slide 66

Slide 66 text

import scala.language.dynamics ! class Dynamap extends Dynamic { ! var map = Map.empty[String, Any] ! def selectDynamic(name: String) = map get name getOrElse sys.error("method not found") ! def updateDynamic(name: String)(value: Any) { map += name -> value } def applyDynamic(name: String)(args: Any*) = name match { case "clear" => map = Map.empty[String, Any] } }

Slide 67

Slide 67 text

import scala.language.dynamics ! class Dynamap extends Dynamic { ! var map = Map.empty[String, Any] ! def selectDynamic(name: String) = map get name getOrElse sys.error("method not found") ! def updateDynamic(name: String)(value: Any) { map += name -> value } def applyDynamic(name: String)(args: Any*) = name match { case "clear" => map = Map.empty[String, Any] } } extends Dynamic selectDynamic updateDynamic applyDynamic

Slide 68

Slide 68 text

val d = new Dynamap ! d.foo = 10 // updateDynamic ! d.foo // selectDynamic ! d.clear() // applyDynamic ! d.foo // ERROR!

Slide 69

Slide 69 text

just because you can doesn’t mean you should…

Slide 70

Slide 70 text

object SquareRoot extends Baysick { def main(args:Array[String]) = { ! 10 PRINT "Enter a number" 20 INPUT 'n 30 PRINT "√ of " % "'n is " % SQRT('n) 40 END ! RUN } }

Slide 71

Slide 71 text

implicit def CokleisliCategory[M[_]: Comonad]: Category[({type λ[α, β]=Cokleisli[M, α, β]})#λ] = new Category[({type λ[α, β]=Cokleisli[M, α, β]})#λ] { def id[A] = ˒(_ copure) def compose[X, Y, Z]( f: Cokleisli[M, Y, Z], g: Cokleisli[M, X, Y]) = { f =<= g } }

Slide 72

Slide 72 text

›(°□°) › ɐlɐɔs

Slide 73

Slide 73 text

def °□° = “” def ɐlɐɔs = “” ! object ››{ def ›(s: String) = "ɐlɐɔs" } ! object ›{ def apply(s: String) = ›› }

Slide 74

Slide 74 text

scala> ›(°□°) › ɐlɐɔs res0: String = ɐlɐɔs

Slide 75

Slide 75 text

practical scalaing 1. simple app 1.1 compiled 1.2 as a script 2. sbt 2.1 scala & sbt are just jars 2.2 maven, gradle fine

Slide 76

Slide 76 text

activator http://typesafe.com/activator

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

technologies

Slide 81

Slide 81 text

web play! 2 finatra scalatra finagle skinny lift socko unfiltered spray

Slide 82

Slide 82 text

object Application extends Controller { def index = Action { Ok(views.html.index(“Hello World")) } } GET / controllers.Application.index App.scala routes play! 2

Slide 83

Slide 83 text

@(title: String)(content: Html) @title @content main.scala.html index.scala.html @(message: String) ! @main {

@message

} play! 2

Slide 84

Slide 84 text

finatra class HelloWorld extends Controller { get("/") { request => render.plain(“Hello World”).toFuture } } ! object App extends FinatraServer { register(new HelloWorld()) }

Slide 85

Slide 85 text

database anorm slick scalalikejdbc squeryl sorm activate reactivemongo casbah

Slide 86

Slide 86 text

anorm SQL( """ SELECT * FROM country c JOIN CountryLanguage l ON l.CountryCode = c.Code WHERE c.code = {countryCode}; """ ).on("countryCode" -> “FRA”)() .map(_[String](“code") -> _[String](“name”)) .toList

Slide 87

Slide 87 text

activate class Person(var name: String) extends Entity ! transactional { new Person(“James Hughes”) } ! val james = transactional { select[Person].where(_.name :== “James Hughes”).head } ! transactional { all[Person].foreach(_.delete) }

Slide 88

Slide 88 text

testing scalatest specs2 scalacheck scalautils

Slide 89

Slide 89 text

scalatest “Empty Set" should "have size 0" in { assert(Set.empty.size == 0) } flat spec test(“Empty set size == 0") { assert(Set.empty.size == 0) } describe("A Set") { it("should have size 0") { assert(Set.empty.size == 0) } } functional suite functional spec

Slide 90

Slide 90 text

akka actors https://speakerdeck.com/rayroestenburg/akka-in-action

Slide 91

Slide 91 text

actor

Slide 92

Slide 92 text

actor ⇝ ⇝

Slide 93

Slide 93 text

mailbox actor ref actor ⇝ actor system

Slide 94

Slide 94 text

mailbox actor ref actor ⇝ actor system

Slide 95

Slide 95 text

mailbox actor ref actor actor system ⇝

Slide 96

Slide 96 text

mailbox actor ref actor actor system ⇝

Slide 97

Slide 97 text

mailbox actor ref actor actor system ⇝ actor x

Slide 98

Slide 98 text

actor system actor system ⇝ actor system ⇝ ⇝ actor system

Slide 99

Slide 99 text

for Scala C# Developers Developers