an introduction to scala

48
Scala for Java Scala for Java Developers Developers Mohsen Zainalpour [email protected]

Upload: mohsen-zainalpour

Post on 06-May-2015

560 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: An introduction to scala

Scala for Java DevelopersScala for Java Developers

Mohsen Zainalpour [email protected]

Page 2: An introduction to scala

GoalsGoals• Have an understanding of what Scala is

• Have an interest in learning more

• Go install Scala!

Page 3: An introduction to scala

What is Scala?What is Scala?• A general purpose programming language• A language that runs on the Java VM• Statically typed• An object-oriented language• No primitives or operators, but with singletons• A functional language• A scalable language• Java compatible

Page 4: An introduction to scala

Scala History … 1995 to Scala History … 1995 to 20132013

Brief history of Scala

•Developed by Martin Odersky

o 1995 he learned of Java and wrote functional language that compiled to Java bytecode - Pizza

o Pizza evolved into what we now recognize as Java generics

•Sun approached Odersky in 1997 to write Java 1.1 compiler

•Odersky led javac development from Java 1.1 through 1.4

•In 1999, Odersky joined EPFL to conduct research into improving functional and OO languages•Design of Scala began in 2001 and first release was in 2003

•Early releases of compiler written in Java•Version 2.0.0 introduced a completely rewritten compiler in Scala

•Current version 2.10.1 released in March 2013

Page 5: An introduction to scala

Is Scala a fit?Is Scala a fit?• Core Strengths

o Functional Programmingo Less boilerplate codeo Concurrencyo Java Interoperableo Domain-Specific Languageso XMLo Bridging

• Weaknesseso Syntaxo Mutability

Page 6: An introduction to scala

Getting up and Getting up and runningrunning

Required

•Java 1.5 or greater

•Scala 2.10.1 distribution

Optional

•SBT – Simple Build Tool

•IDE Plugino ScalaIDE (Eclipse – must use Helios)

o Scala Plugin for IntelliJ IDEA

o Scala Plugin for NetBeans

Page 7: An introduction to scala

Scala cheat sheetScala cheat sheet

Page 8: An introduction to scala

DefinitionsDefinitionsScala method definitions:def fun(x: Int): Int = { result }

def fun = result

Scala variable definitions:var x: Int = 10val y: String = "Scala"

Java method definition:int fun(int x) {

return result}

(no parameterless methods) Java

variable definitions:int x = 10final String x = "Scala"

Page 9: An introduction to scala

Objects and ClassesObjects and ClassesScala Class and Object

class Sample(x: Int, val p: Int) { def instMeth(y: Int) = x + y}

object Sample { def staticMeth(x: Int, y: Int) = x * y}

Java Class with statics

public class Sample { private final int x; public final int p;

Sample(int x, int p) { this.x = x; this.p = p; }

int instMeth(int y) { return x + y; }

static int staticMeth(int x, int y) { return x * y; }}

Page 10: An introduction to scala

TraitsTraitsScala Trait

trait T { var field = "!"

def abstractMth(x: String): Int

def concreteMth(x: String) = x + field}

Scala mixin composition:

class C extends Super with T

Java Interface

interface T {int abstractMth(String x)

}

(no concrete methods) (no fields)

Java extension + implementation:

class C extends Super implements T

Page 11: An introduction to scala

ConstructorsConstructorsclass Person(val firstName: String, val lastName: String) { private var position: String = _ println("Creating " + toString())

def this(firstName: String, lastName: String, positionHeld: String) { this(firstName, lastName) position = positionHeld }

override def toString(): String = { firstName + " " + lastName + " holds " + position + " position " }}

Page 12: An introduction to scala

Statics in ScalaStatics in Scalaclass Marker private(val color: String) { override def toString(): String = "marker co1or " + color}

object Marker { private val markers = Map( "red" -> new Marker("red"), "b1ue" -> new Marker("blue"), "green" -> new Marker("green") )

def primaryColors = "red, green, blue"

def apply(color: String) = if (markers.contains(color)) markers(color) else null}

object MarkerTest extends App { println("Primary co1ors are · " + Marker.primaryColors) println(Marker("blue")) println(Marker("red"))}

Page 13: An introduction to scala

Higher Order Higher Order FunctionsFunctions

These are functions that take other functions as parameters, or whose result is a function.

class Decorator(left: String, right: String) { def layout[A](x: A) = left + x.toString() + right}

object FunTest extends App { def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7))}

Page 14: An introduction to scala

Currying & Partial Currying & Partial FunctionsFunctions

Methods may define multiple parameter lists. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.

object CurryTest extends App {

def filter(xs: List[Int], p: Int => Boolean): List[Int] = if (xs.isEmpty) xs else if (p(xs.head)) xs.head :: filter(xs.tail, p) else filter(xs.tail, p)

def modN(n: Int)(x: Int) = ((x % n) == 0)

val nums = List(1, 2, 3, 4, 5, 6, 7, 8) println(filter(nums, modN(2))) println(filter(nums, modN(3)))}

Page 15: An introduction to scala

ClosuresClosuresYou can create code blocks with variables that are not bound.You will have to bind them before you can invoke the function; however,they could bind to, or close over, variables outside of their local scopeand parameter list.That’s why they’re called closures.

•A closure allows a function to access variables outside its immediate lexical scope.

Val outer:String=“scala”Val f:( String => Unit) = { (x:String) => println(x + “ “ + outer)

Page 16: An introduction to scala

TraitsTraitsThey are fundamental unit for code reuse in ScalaA Trait encapsulates method and field definitions, which can bereused by mixing them in classesUnlike class inheritance , in which class must inherit from just onesuperclass, a class may mix in any number of Traits

Unlike Interfaces they can have concrete methods

Page 17: An introduction to scala

import scala.collection.mutable.ArrayBuffer

//Type Definitionabstract class IntQueue { def get(): Int

def put(x: Int)

def size(): Int}

//ArrayBuffer implementationclass IntQueueImpl extends IntQueue { private val buf = new ArrayBuffer[Int]

def get = buf remove 0

def put(x: Int) { buf += x }

def size = buf length}

trait Doubling extends IntQueue { abstract override def put(x: Int) { super.put(2 * x) }}

trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) }}

trait Filtering extends IntQueue { abstract override def put(x: Int) { if (x > 0) super.put(x) }}

//Mixing traits in type definitionclass DoublePlusOneQueue extends IntQueueImpl with Incrementing with Doubling

object QueueWithTraits { def main(args: Array[String]) { val queue1 = new DoublePlusOneQueue queue1 put 1 queue1 put 2 println(queue1 get) println(queue1 get)

//Mixing traits in object instantiation val queue2 = new IntQueueImpl with Filtering queue2 put -1 queue2 put 1 println(queue2 size) }}

Page 18: An introduction to scala

Pattern MatchingPattern MatchingScala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy. 

object MatchTest2 extends App { def matchTest(x: Any): Any = x match { case 1 => "one" case "two" => 2 case y: Int => "scala.Int" }

println(matchTest("two")) println(matchTest(100))}

Page 19: An introduction to scala

CollectionsCollectionsBasic Data Structures•Lists

val numbers = List(1, 2, 3, 4)•Sets

Set(1, 1, 2)•Tuple

val hostPort = ("localhost", 80)•Maps

Map(1 -> 2)

Functional Combinators •Map

scala> numbers.map((i: Int) => i * 2) res0: List[Int] = List(2, 4, 6, 8)

•Foreachnumbers.foreach((i: Int) => i * 2)

Page 20: An introduction to scala

CollectionsCollections• Filter

scala> numbers.filter((i: Int) => i % 2 == 0) res0: List[Int] = List(2, 4)

• Zipscala> List(1, 2, 3).zip(List("a", "b", "c")) res0: List[(Int, String)] = List((1,a), (2,b), (3,c))

• Partitionscala> val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> numbers.partition(_ %2 == 0) res0: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))

• Findscala> numbers.find((i: Int) => i > 5) res0: Option[Int] = Some(6)

• drop and dropWhilescala> numbers.drop(5) res0: List[Int] = List(6, 7, 8, 9, 10)

Page 21: An introduction to scala

CollectionsCollections• foldRight and foldLeft

scala> numbers.foldLeft(0)((m: Int, n: Int) => m + n)res0: Int = 55

scala> numbers.foldLeft(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n } m: 0 n: 1 m: 1 n: 2 m: 3 n: 3 m: 6 n: 4 m: 10 n: 5 m: 15 n: 6 m: 21 n: 7 m: 28 n: 8 m: 36 n: 9 m: 45 n: 10

res0: Int = 55

Page 22: An introduction to scala

CollectionsCollections• Flatten

scala> List(List(1, 2), List(3, 4)).flatten res0: List[Int] = List(1, 2, 3, 4)

• flatMapscala> val nestedNumbers = List(List(1, 2), List(3, 4)) nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4))

scala> nestedNumbers.flatMap(x => x.map(_ * 2)) res0: List[Int] = List(2, 4, 6, 8)

• Generalized functional combinatorsevery functional combinator shown above can be written on top of fold.

def ourMap(numbers: List[Int], fn: Int => Int): List[Int] = { numbers.foldRight(List[Int]()) { (x: Int, xs: List[Int]) => fn(x) :: xs } }

scala> ourMap(numbers, timesTwo(_)) res0: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

Page 23: An introduction to scala

Scala FeaturesScala Features

Page 24: An introduction to scala

Functional Functional programmingprogramming

• The functional paradigm expresses programs as functions in the mathematical sense, mapping from one value to another (f (x) = y)

• without side effects, such as :o maintaining the status of objects o input/output of data

• Features such as :o immutable valueso collectionso higher-order functionso pattern matching encourages Scala developers to use the functional style.

Page 25: An introduction to scala

a program that prints the thousandth element of the Fibonacci sequence can be written as follows in Java:

import java.math.BigInteger; public class FiboJava { private static BigInteger fibo(int x) { BigInteger a = BigInteger.ZERO; BigInteger b = BigInteger.ONE; BigInteger c = BigInteger.ZERO; for (int i = 0; i < x; i++) { c = a.add(b); a = b; b = c; } return a; }  public static void main(String args[]) { System.out.println(fibo(1000)); }}

Page 26: An introduction to scala

a more compact and functional version, using infinite sequences and tuples can be very different:

import scala.math.BigInt

object Main extends App {

val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }

fibs take 5 foreach println}

Page 27: An introduction to scala

java 8 Lambda projectjava 8 Lambda projectLambda Expressions as Functions

•A lambda expression is a function literal. It defines a function with input parameters and function body. (String s1, String s2) -> s1.length() - s2.length();

Lambda Expression as Closures•A closure allows a function to access variables outside its immediate lexical scope.

String outer = "Java 8" (String s1) -> s1.length() - outer.length()

Hello Lambda Expressions, Goodbye Anonymous Inner Classesclass UIBuilder {   

public UIBuilder() {       button.addActionListener(e -> //process ActionEvent e)   } }

Higher-Order Functions as Reusable Building BlocksWhen we pass a function literal to a method, we basically have a method that accepts a method. Such methods are called higher-order functions.

def measure[T](func: => T):T = {       val start = System.nanoTime()       val result = func       val elapsed = System.nanoTime() - start       println("The execution of this call took: %s ns".format(elapsed))       result }

def myCallback = {       Thread.sleep(1000)       "I just took a powernap" } val result = measure(myCallback);

Page 28: An introduction to scala

Less boilerplate codeLess boilerplate codeSome Scala features, such as :• type inference• unchecked exceptions• optional objects• implicit conversions can greatly reduce the amount of statements and checks in a program, without changing its meaning.

Page 29: An introduction to scala

In Java:import java.net.NetworkInterface;import java.net.SocketException;import java.util.Collections;import java.util.Enumeration;

public class ListMACsJava { public static void main(String[] args) throws SocketException { Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface nic : Collections.list(nics)) { byte[] mac = nic.getHardwareAddress(); for (int i = 0; mac != null && i < mac.length; i++) { System.out.format("%2x", mac[i]); System.out.print(i == mac.length - 1 ? '\n' : ':'); } } }}

Page 30: An introduction to scala

In Scala:import java.net.NetworkInterfaceimport scala.collection.JavaConversions._

object ListMACsScala { def main(args: Array[String]) { NetworkInterface .getNetworkInterfaces .flatMap(nic => Option(nic.getHardwareAddress)) .map(_ map ("%02x" format _) mkString ":") .foreach(println(_)) }}

Page 31: An introduction to scala

Or, another implementation in Scala using sequence comprehension :

import java.net.NetworkInterfaceimport scala.collection.JavaConversions._

object ListMACsScala { def main(args: Array[String]) { val nicaddresses = for { nic <- NetworkInterface.getNetworkInterfaces addrbytes <- Option(nic.getHardwareAddress) } yield { addrbytes map { "%02x" format _ } mkString ":" } nicaddresses foreach println }}

Page 32: An introduction to scala

Does Scala offer better Does Scala offer better

concurrency?concurrency?“If it hurts, stop doing it” is a doctor’s good advice. In concurrent program-ming, shared mutability is “it.”

Shared mutability—the root of concurrency roblems—is where multiple threads can modify a variable.

Solution :

•Immutability•Actors

Page 33: An introduction to scala

ImmutabilityImmutability• Synchronizing access to shared mutable objects

can result in much complexity in the use of concurrency primitive (locks, semaphores, etc.).

• Scala tries to mitigate this problem by using immutable objects and pure functions

• If an object is immutable, it can be shared or copied without worrying about who is using it, so it is naturally "thread-safe."

Page 34: An introduction to scala

ActorsActors• Using Low-level parallelism controls, such as

locks and synchronized blocks may not be easy.

• to write this type of program more productively and prevent defects, a high level concurrency control is very desirable. Such abstraction can be like o Fork /Joino Software Transactional Memoryo or, as featured in Scala, the Actor Model. In Actor Model, the parallelism is expressed as actors reacting to messages, rather than locking and releasing of threads.

Page 35: An introduction to scala
Page 36: An introduction to scala
Page 37: An introduction to scala

The following example demonstrates actors estimating the value of Pi using the Monte Carlo method.

import scala.util.Randomimport Math._import scala.actors.Actor

case object Calculate

case object ShutDown

class Calculator extends Actor { val rand = new Random var in, cnt = 1.0

def act { while (true) { receive { case Calculate => sender ! estimativeOfPi case ShutDown => exit } } }

def estimativeOfPi: Double = { val x = rand.nextDouble - 0.5 val y = rand.nextDouble - 0.5 cnt += 1.0 if (sqrt(x * x + y * y) < 0.5) in += 1 in / cnt * 4 }}

Page 38: An introduction to scala

The "coordinator" starts a list of calculators and tell them to calculate until any of them produces an accurate enough estimation

import actors.Actor

class Coordinator(numOfCalculators: Int) extends Actor { def act { val startedAt = System.currentTimeMillis() var calculators = List.fill(numOfCalculators)(new Calculator) calculators.foreach(c => { c.start c ! Calculate }) while (true) { receive { case estimative: Double => val error = Math.abs(Math.PI - estimative) if (error > 0.0000001) sender ! Calculate else { val tempo = System.currentTimeMillis() - startedAt calculators.foreach(_ ! ShutDown) println("Pi found by " + sender + " = " + estimative) println("Execution time: " + tempo) exit } } } }}

object PiActors extends App { new Coordinator(2) start}

Page 39: An introduction to scala

Parallel CollectionsParallel CollectionsScala 2.9 introduced parallel collections, which makes it easy to parallelize the execution of common collections operations, such as map(), filter () and foreach(). The par() method can be used to obtain a parallel version of the collection

object ParCol extends App { (1 to 5) foreach println (1 to 5).par foreach println}

Page 40: An introduction to scala

XMLXMLAn interesting combination in Scala is the XML syntax in combinationwith pattern matching.

val movies = <movies> <movie>The Incredibles</movie> <movie>WALL E</movie> <short>Jack Jack Attack</short> <short>Geri's Game</short> </movies> (movies \ "_").foreach { movie => movie match { case <movie>{movieName}</movie> => println(movieName) case <short>{shortName}</short> => println(shortName + " (short)") } }

Page 41: An introduction to scala

Is Scala extensible?Is Scala extensible?Scala allows developers to customize the look and feel of the language, creating new languages and altering the compilation process.

Page 42: An introduction to scala

Domain Specific Domain Specific LanguagesLanguages

Using generic classes, abstract types, functions as objects, methods named as operators and implicit conversions, Scala code can become a domain specific language (DSL).

Domain-specific languages can also be created when a more abstract and declarative language is needed by developers. For example, Apache Camel offers a Scala DSL to make the configuration of service routes more concise and correct.

 "direct:a" ==> { to ("mock:polyglot") choice { when (_.in == "<hello/>") to ("mock:english") when (_.in == "<hallo/>") { to ("mock:dutch") to ("mock:german") } otherwise to ("mock:french") }}

Page 43: An introduction to scala

Changing the Changing the compilationcompilation

• allowing the creation of entirely new grammars with parser combinators.

• create compiler plugins to change the build process. These plugins could be written, for :operform static code analysis .oevaluating metrics, like PMD or FindBugs.

Page 44: An introduction to scala

Are Scala and Java Are Scala and Java interoperable?interoperable?

• it is possible to invoke Java methods in Scala code and vice versa.

• When calling Scala methods from Java, the developer needs to understand how the features that do not exist in Java. For example:o methods with non-alphabetic nameso receiving functions o tuples as parameters

• When invoking Java from Scala, the problems is the features of Java that were abandoned or implemented differently in Scala, such as :o interfaceso annotations o collections

Page 45: An introduction to scala

Using Java Libraries Using Java Libraries and Frameworks in and Frameworks in

ScalaScalaany library or framework available for Java can be used in Scala. This includes all Java EE (EJB, JSF, JAX-RS, etc.) and popular libraries, such as Hibernate and Junit.

import javax.servlet.http._import javax.servlet.annotation.WebServlet

import scala.collection.JavaConversions._

@WebServlet(Array("/printParams"))class PrintParametersServlet extends HttpServlet { override def

doGet(req:HttpServletRequest, resp:HttpServletResponse) { val out = resp.getWriter req.getParameterMap.map { case (key,value)=>key + " = " + value.mkString(",") }.foreach(out println _) }}

Page 46: An introduction to scala

Final ThoughtsFinal ThoughtsScala is appropriate for an application that has significant scalability requirements that requires concurrency

Page 47: An introduction to scala

Q & AQ & A

Page 48: An introduction to scala

Thank YouThank [email protected]