scala in a nutshell

39
Scala in a nutshell Kyel John. David Software Engineer

Upload: kyel-john-m-david

Post on 17-Jul-2015

134 views

Category:

Technology


3 download

TRANSCRIPT

Scala in a nutshellKyel John. David

Software Engineer

DISCLAIMER

Some of the examples will be very crud. Purpose of theexamples just to get the basic ideas/concepts out

What is ScalaScala is both functional and object oriented languagethat operates under the JVM.Acronym for "Scalable Language"Supported by TypeSafe Inc

Why ScalaBoth Functional and Object OrientedJVM Based languageHigher Order Functions(Functionsas value Types)"expressive" and "concise"Almost all Java libraries can be used by ScalaEasier to write multi-threaded applicationsPartial FunctionsPattern MatchingAnd more....

Basics

Variable Assignments and Declarationsscala> var stockPrice = 20.00stockPrice: Double = 20.0

scala> var stockPrice = 40.00stockPrice: Double = 40.0

scala> val numOfShares = 32numOfShares: Int = 32

scala> numOfShares = 122<console>:8: error: reassignment to val numOfShares = 122 ^

scala> val distance = val dx = x ­ x0; val dy = y ­ y0; sqrt(dx * dx + dy * dy)

scala> val person = new Person("Kyel",21)

val - (Read-only)

var - (Read-Write)

Variable Assignments and Declarations

//Specifying type information

scala> val person:Person = new Person("Kyel",21)

scala> val listItems: List[Int] = List(1,2,3,4,5)

Loops

/**Range Generates a /*sequence of Inclusive/exclusive /*sequence <start> to/until <end> <by increment>**/

scala> 0 to 10res7: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> 0 to 10 by 2res11: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8, 10)

scala> 0 until 10 by 2res12: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8)

For comprehension

for(i <­ 1 to 10) println(i)

for i <­ 1 to 10 println(i)

//Iterator Guardfor(i <­ 1 to 10; if i % 2== 0; x2 = i * 2) println(i)//Value bindingfor(i <­ 1 to 10; x2 = i * 2; if i % 2 == 0 ) println(x2)

"For yield"

for i <­ 1 to 10yield i

res5: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Function Definitionsscala> def abs(n: Int): Int = if(n < 0) ­n else n abs: (n: Int)Int

scala> def abs(n: Int): Int = if(n < 0) ­n else nabs: (n: Int)Int

scala> def abs(n: Int) = if(n < 0) ­n else nabs: (n: Int)Int

//"Generic" Function. //Type informationscala> def someOperation[A](x: A) = x someOperation: [A](x: A)A

//Another Syntactic sugar for Scala when writing //a function that has no argumentsscala> def noParameterFunction = println("A function of no parameter") noParameterFunction: Unit

Function Definitionsdef signum(n: Int): Int = if(n>0) 1 else 0

def factorial(i: Int) = @tailrec def fact(i: Int, accumulator: Int): Int = if (i <= 1) accumulator else fact(i ­ 1, i * accumulator)

fact(i, 1)

//Prodedures in Scala, function definition//that returns Unit //no '='def procedure(x: Any) print(x)

Function Type and Literals

scala> (x: Int, y: Int) => if( x > y ) x else y(Int, Int) => Int = <function2>

scala> val max = res1max: (Int, Int) => Int = <function2>

Basic example of a function typeInt => Int

Function Literals - Function with no names(Lambdas inother language/Anonymous function)

HOF - Functionsdef factorial(f: String => Unit) = f("Hello, World!")

def operation(f: (Int,Int) => Int,x:Int, y:Int ): Int = f(x,y)

//An example of function compositiondef func[A,B,C](f1: A => B, f2: B=>C): A => C = (a:A) => f2(f1(a))

The _ operatorscala> def stringOps(s: String, f1: String => String) = | if (s == null) " " else f1(s) |

scala> val reverseString:String => String = (s:String) => s.reversereverseString: String => String = <function1>

scala> stringOps("Hello World",reverseString)res12: String = dlroW olleH

//The magic of the "_" operatorscala> stringOps("Hello World", _.reverse)res11: String = dlroW olleH

//Another way of declaring the reverseString functionscala> val reverseString:String => String = _.reversereverseString: String => String = <function1>

Ex of Java to Scalacase class Message(message: String)

def sendPostcards: List[Message] =

val posters = List("John", "Lloyd", "Cruz" "Bea Alonzo", "Nina Dobrev", "Georgina Wilson", "Ashton Kutcher", "Solenn Heussaff", "Mila Kunis", "Marian Rivera")

val senders= List("Ding Dong", "Marian")

var messageList: List[Message] = List()

for (h <­ 0 until posters.length) val sender = posters(h) for (i <­ 0 until senders.length) messageList ::= new Message("Dear " + "Thank you for your wonderful Love, " + sender)

messageList

Cleaning it updef sendPostcards: List[Message] = val posters = List("John", "Lloyd", "Cruz" "Bea Alonzo", "Nina Dobrev", "Georgina Wilson", "Ashton Kutcher", "Solenn Heussaff", "Mila Kunis", "Marian Rivera") val senders= List("Ding Dong", "Marian") for h <­ 0 until posters.length recipient = poster(h) i <­ 0 until senders.length; sender = senders(i) yield new Message("Dear " + recipient + ", " + "Thank you for your wonderful greeting " "Love, " + sender)

Case ClassesThink of them as value objects or DTOsAll fields are immutableNo more boilerplate code(hashCode and equals hasbeen generated)Can be used for Pattern MatchingMaximum of 22 fields only

Case Classesscala> case class Person(name: String, age: Int)defined class Person

scala> val person1 = Person("Kyel",21)person1: Person = Person(Kyel,21)

scala> val person2 = Person("Kyel",21)person2: Person = Person(Kyel,21)

scala> person1 == person2res10: Boolean = true

Classesscala> class PatientInfo(n: String) | val name = n | def greet = s"Hello, I am $name" | override def toString = s"PatientInfo($name)" |

//Cleaner way way of declaring a classscala> class PatientInfo(val name: String) | def greet = s"Hello, I am $name" | override def toString = s"PatientInfo($name)" | defined class PatientInfo

Inheritancescala> class A | def hi = "Hello from A" | override def toString = getClass.getName | defined class A

scala> class B extends Adefined class B

scala> class C extends B | override def hi = "Hello From C ­>" + super.hi | defined class C

scala> new C().hires5: String = Hello From C ­> Hello From A

Polymorphismscala> val a: A = new Aa: A = A

scala> val a: A = new Ba: A = B

scala> val b: B = new A<console>:9: error: type mismatch; found : A required: B val b: B = new A ^

scala> val b: B = new Bb: B = B

Named Parametersscala> class Vehicle(val make: String, var reserve: Boolean) | def setReserve(r:Boolean):Unit = reserve = r | defined class Vehicle

scala> vios.reserveres0: Boolean = true

scala> vios.setReserve(false)

scala> vios.reserveres2: Boolean = false

scala> val roadster = new Vehicle(reserve = true, make = "Tesla")

Another Example of Inheritance

scala> class Vehicle(val make: String, var reserve: Boolean) | def setReserve(r:Boolean):Unit = reserve = r | defined class Vehicle

scala> class Sedan(val color: String, reserved: Boolean,make:String)| extends Vehicle(make, reserved)defined class Sedan

scala> val vios = new Sedan("Red",false,"Toyota")vios: Sedan = Sedan@b11975

scala> println(s"Requested a $vios.color $vios.make")Requested a Red Toyota

Classes with Type Parameters

scala> class Singular[A](element: A) extends Traversable[A] | def foreach[B](f: A => B) = f(element) | defined class Singular

scala> val p = new Singular("Planes")p: Singular[String] = (Planes)

scala> p foreach println Planes

scala> val name: String = p.head name: String = Planes

Classes with Default Values

scala> class Car(val make: String, var reserved: Boolean = true, | val year: Int = 2015) | override def toString = s"$year $make, reserved = $reserved" | defined class Car

scala> val a = new Car("Toyota") a: Car = 2015 Toyota, reserved = true

scala> val l = new Car("Lexus", year = 2010) l: Car = 2010 Lexus, reserved = true

scala> val p = new Car(reserved = false, make = "Volvo") p: Car = 2015 Volvo, reserved = false

Abstract Classes

scala> abstract class Car | val year: Int | val automatic: Boolean = true | def color: String | defined class Car

scala> new Car()<console>:9: error: class Car is abstract; cannot be instantiated new Car()

scala> class RedMini(val year: Int) extends Car | def color = "Red" | defined class RedMini

scala> val m: Car = new RedMini(2005)m: Car = RedMini@5f5a33ed

Object

scala> object HtmlUtils | def removeMarkup(input: String) = | input | .replaceAll("""</?\w[^>]*>""","") | .replaceAll("<.*>","") | | defined object HtmlUtils

Traitsscala> trait Person | def walk(): Unit | defined trait Person

scala> class Student(val name: String) extends Person | def walk(): Unit = println(s"$name Just walked") | defined class Student

scala> val kyel = new Student("Kyel")kyel: Student = Student@6e709631

scala> kyel.walkKyel Just walked

scala> trait Person | def walk():Unit = println("Walking") | defined trait Person

Pattern MatchingCase keyword on steroidsAlgebraic data types "pattern matching is a way of assigning names to things(or binding those names to those things), and possiblybreaking down expressions into subexpressions at thesame time" Allows you to "Pattern" match -Strings-Numbers-Regular Expressions-Case classes

Pattern Matchingscala> val message = "hello" message: String = "hello"

scala> val person1 = Person("Kyel",21)person1: Person = Person(Kyel,21)

def identifyType(item: Any) = item match case s:String => "The received type argument is a String" case i:Int => "The received type argument is an Int" case d:Double => "The received type argument is a Double" case _ => "Type Not Supported"

scala> identifyType(message)res6: String = The Received Argument is a String

scala> identifyType(person1)res8: String = Type Not Supported

Collections Framework

Lists, Sets, and MapHas immutable and mutable implHas Map, Reduce, and more implementationsPattern MatchingSupport for HOF

Collections Framework

scala> val fruits = List("Apple","Banana","Watermelon")fruits: List[String] = List(Apple, Banana, Watermelon)

scala> val states = Map(1500 ­>"San Juan", 1690 ­> "Makati", 1300 ­> "Pasig", 1000 ­> "Quezon City")states: scala.collection.immutable.Map[Int,String] = Map(1500 ­> San Juan, 1690 ­> Makati, 1300 ­> Pasig, 1000 ­> Quezon City)

scala> val nums = Set(1,1,2,3,4,5,6,7,8,9,10)nums: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)

Basic Operationsscala> fruits(2)res2: String = Watermelon

scala> fruits.headres3: String = Apple

scala> fruits.tailres4: List[String] = List(Banana, Watermelon)

scala> fruits :+ "Durian"res12: List[String] = List(Apple, Banana, Watermelon, Durian)

scala> fruits.foreach(x => println(x))AppleBananaWatermelon

scala> for(i <­ 0 until fruits.length) println ( fruits(i) )AppleBananaWatermelon

Reduce Operationsscala> List(4, 5, 6).fold(0)(_ + _)res2: Int = 15

scala> List(4, 5, 6).foldRight(0)(_ + _)res10: Int = 15

scala> List(4, 5, 6).reduce(_ + _)res12: Int = 15

scala> List(4, 5, 6).reduceLeft(_ + _)res14: Int = 15

List(4, 5, 6).reduceRight(_ + _)res17: Int = 15

Map Operationsscala> val colors = List("red", "green", "blue")colors: List[String] = List(red, green, blue)

scala> colors.foreach( (c: String) => println(c) ) 1redgreenblue

scala> val sizes = colors.map( (c: String) => c.size ) 2sizes: List[Int] = List(3, 5, 4)

Fold vs Fold/Left/Right

Fold operation returns the same type as the elementson the listleft/right varieties of each operation support uniquereturn typesFold has no order of operationsLeft only requires fewer traversals compared to right

Pattern Matchingscala> case class Human(name:String, gender:String)defined class Human

scala> val human1 = new Human("John","male")human1: Human = Human(John,male)

scala> val human2 = new Human("Keith","Female")human2: Human = Human(Keith,Female)

scala> val human3 = new Human("Angela","Female")human3: Human = Human(Angela,Female)

scala> val humans = List(human1,human2,human3)humans: List[Human] = List(Human(John,male), Human(Keith,Female), Human(Angela,Female))

scala> humans match | case x if x contains(human3) => "true" | res5: Boolean = true

Other Resources

Exerciseshttp://www.scalakata.com/

Community Driven Scala DocWhat is Functiol programmingScala Collections for the Easily Bored Part 1 Scala Collections for the Easily Bored Part 2Scala Collections for the Easily Bored Part 3

Fin