46
A first date with Scala Franco Lombardo XP User Group - Bergamo http://www.francolombardo.net Edward Hopper - Summertime

A First Date With Scala

Embed Size (px)

Citation preview

Page 1: A First Date With Scala

A first date with Scala

Franco LombardoXP User Group - Bergamo

http://www.francolombardo.net

Edward Hopper - Summertime

Page 2: A First Date With Scala

First of all, you must know…

http://www.francolombardo.net

…I’m not a Guru!!!

Page 3: A First Date With Scala

Scala: passport• IT was born in 2001 at the

Ecoles Polytechniques fédérales de Lausanne

• Firs public release in 2004• Ideated by Martin Odersky,

the father of Java “Generics”

• The compiler generates .class file for the JVM (someone says there’s also a version for .NET )

http://www.francolombardo.net

Claudio Destito – Auto-ritratto

Page 4: A First Date With Scala

Scala = SCAlable LAnguage

http://www.francolombardo.net

In order to “scale” you need solid basis!

• Widespread virtual machine• Libraries/frameworks/application servers created in Java are immediately available in Scala• Base syntax very close to Java, so it’s very appealing for a great number of programmers

The base of Scala is Java

Page 5: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Yet another Hello World programRunning on JMV 1.6.0_13On Sat May 23 17:36:34 CEST 2009

Output

Page 6: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Basic syntax very close to Java

Page 7: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Object from java.lang are imported by default

Page 8: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Object from Java libraries are easly avaible

Page 9: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Simplified syntax: semicolon is not mandatory

Page 10: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Simplified syntax: less code

Page 11: A First Date With Scala

Here is our star: Hello World!!!

http://www.francolombardo.net

package hello

import java.util.Date

object Hello extends Application { println("Yet another Hello World program")

val jvmVer = System.getProperty("java.version") println("Running on JMV " + jvmVer)

println("On " + new Date())}

Simplified syntax: type inference

Page 12: A First Date With Scala

http://www.francolombardo.net

//Java return customer.getOrder(40) .getRow(20) .getItem() .getWeight() * 2.5;

Type inference: have you ever seen it?

(OK, in this example we do not obey Demeter law, but it’s only an example…)

Page 13: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: static typing

• The compiler gives lots of automatic tests on the code for free

• Enhanced refactorings• Better average performances (OK, not always, but

Scala substituted Ruby at Twitter for performances issues)

• Static typing is a clear and automatic tool for code documentation

Page 14: A First Date With Scala

http://www.francolombardo.net

Tools for scalbility: “pure” Object Orientation

• Every value is an object• Every operation is a method call (so we can

redefine operators easily) 2 + 5 //equals to... 2.+(5)

Syntactic tricks to improve readability:• Starting method names with letters is not mandatory• In some cases points and parenthesis are not mandatory

Page 15: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

• A problem of big Object Oriented systems: objects that can become very fat

Fernando Botero – Bailerina na barra

Page 16: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Javapublic class Customer {

public String name() { //some implementation… } public String address() { //some implementation }

• Fat objects: the Customer

Page 17: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Javapublic class Customer { //… public Bank preferredBank() { //some implementation… } public Solvability solvability() { //some implementation… }

• Fat objects: the Customer for accounting purposes

Page 18: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Javapublic class Customer { //… public Agent zoneAgent() { //some implementation… } public Boolean isToSendEMails() { //some implementation… }

• Fat Objects: the Customer for the CRM system

Page 19: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Javapublic class Customer { //… public Carrier[] carriers() { //some implementation… } public Discount[] discounts() { //some implementation… }

• Fat objects: the Customer for orders

Page 20: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Javapublic class Customer { //… public Priority schedulingPriority() { //some implementation… } public TechnicalInfo[] standards() { //some implementation… }

• Fat objects: the Customer for production

Page 21: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

• Fat objects: does inheritance help?Customer

name()address()

AccountingCustomer

preferredBank()

solvability()

CRMCustomer

zoneAgent()

isToSendEMails()

ProductionCustomer

schedulingPriority()

standards()

• What if I needed the preferred bank in the CRM module?

Page 22: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Scalacase class Customer(name: String, address: String)

trait accountingCstomer { def preferredBank = //some implementation def solvability = //some implementation}

trait CRMCustomer { def zoneAgent = //some implementation def isToSendEMail = //implementation}

• Fat objects: decomposing with Traits

Page 23: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: Object Orientation with Traits

//Scalaval customer = new Customer(“Lombardo ltd", “Wall Street, 1") with CRMCustomer with AccountingCustomer

• Fat objects: decomposing with Traits

“Dynamic” type composition

Page 24: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

• Functions are base objects of the language, as strings and numbers

• Therefore functions can be arguments and return values of method calls

You can decompose the system in generic functions which you can reuse reducing duplications

Higher order functions

Page 25: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

• Functions don’t have a state: their results are based only on input values.

• A function evaluation has no side effects beside the computation of the result

• Reusing functions is simpler if we don’t need to reproduce a particular state

• We can test code more easily

Referential transparency

Page 26: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

An example: numeric integration…

Page 27: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

…I was joking, let’s use a more “concrete” example

//Here’s an order rowcase class OrderRow(description: String, price: Double, qty: Double) { def amount = price * qty}

//And an orderval order = List(OrderRow("Beer", 5.0, 2), OrderRow("Chips", 2.5, 1))

Page 28: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

//A traditional approach to VAT computation var total = 0.0 for (row <- order) { total += row.amount *0.2 } println("VAT (Total): " + total);

Page 29: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

//A traditional approach to VAT computation var total = 0.0 for (row <- order) { total += row.amount *0.2 } println("VAT (Total): " + total);

We merge 3 operations• Loop

Page 30: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

//A traditional approach to VAT computation var total = 0.0 for (row <- order) { total += row.amount *0.2 } println("VAT (Total): " + total);

We merge 3 operations• Loop• Accumulation

Page 31: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

//A traditional approach to VAT computation var total = 0.0 for (row <- order) { total += row.amount *0.2 } println("VAT (Total): " + total);

We merge 3 operations• Loop• Accumulation

• Computation

Page 32: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

//The computation: it’s a function we can assignval vat = (row: OrderRow) => row.amount * 0.2

//Composition of accumulation and computationdef composition(aggr: (Double, Double) => Double, calculus: (OrderRow => Double)) (partial: Double, row: OrderRow) = aggr(partial, calculus(row))

val totalVat = order.foldLeft(0.0)(composition(_+_, vat))

Let’s decompose these 3 operations

Page 33: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

val totalVat = order.foldLeft(0.0)(composition(_+_, vat))

Let’s decompose these 3 operations

• Loop//Java B b = start; for(final A a : listOfA) { b = method(b, a); } return b;

//ScalalistOfA.foldLeft(start)(method)

Page 34: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

val totalVat = order.foldLeft(0.0)(composition(_+_, vat))

Let’s decompose these 3 operations

• Loop• Accumulation

Page 35: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

val totalVat = order.foldLeft(0.0)(composition(_+_, vat))

Let’s decompose these 3 operations

• Loop• Accumulation• Computation

Page 36: A First Date With Scala

http://www.francolombardo.net

Tools for scalability: functional programming

val totalAmount = order.foldLeft(0.0)(composition(_+_, _.amount))val maxAmount = order.foldLeft(0.0)(composition(Math.max, _.amount))val maxVat = order.foldLeft(0.0)(composition(Math.max, vat))

We can recompose them in a different way

Page 37: A First Date With Scala

http://www.francolombardo.net

Structural types

def deleteAllRows(statement: java.sql.Statement) = statement.execute("DELETE FROM MYTABLE")

How can we test this method?

An hand written mock?

The java.sql.Statement interface has 41 methods!!!

(Well, I don’t like frameworks…)

Page 38: A First Date With Scala

http://www.francolombardo.net

Structural types

def deleteAllRows( statement: {def execute(sql: String): Boolean}) = statement.execute("DELETE FROM MYTABLE")

Let’s modify our method declaring only what we need

Page 39: A First Date With Scala

http://www.francolombardo.net

Structural types

def testDeleteAllRows() { val mockStatement = new { def execute(sql: String) = { println(sql) //Oppure qualsiasi cosa x test true //Valore di ritorno di execute } }

deleteAllRows(mockStatement)}

Now we can test our code easily

Page 40: A First Date With Scala

http://www.francolombardo.net

Implicit conversions

class RemoteStatement { def remoteExecute(sql: String) = { println(sql + " executed remotely :-)") true }}

What if we’d need to use a library for doing remote queries?

Page 41: A First Date With Scala

http://www.francolombardo.net

Implicit conversions

implicit def normalize(remote: RemoteStatement) = new {

def execute(sql: String) = remote.remoteExecute(sql) }

//I can use it even if it is not the exact type!deleteAllRows(new RemoteStatement)

No problem: we can convert on the fly!

Page 42: A First Date With Scala

http://www.francolombardo.net

Domain Specific Languages

val tenDollars = (4.0 USD) + (6.0 USD)

I’d like to write something like this

Andy Warhol– Dollar sign

Page 43: A First Date With Scala

http://www.francolombardo.net

Domain Specific Languages

abstract class Currency {def name: String;override def toString = name

}

object Euro extends Currency {def name ="EUR"

}

object Dollar extends Currency {def name = "USD"

}

No problem!

Page 44: A First Date With Scala

http://www.francolombardo.net

Domain Specific Languages

case class Money[C <: Currency](amount: Double, currency: C) { def + (otherMoney: Money[C]) =

new Money(amount + otherMoney.amount, currency)

override def toString = amount + " " + currency}

No problem!

Page 45: A First Date With Scala

http://www.francolombardo.net

Domain Specific Languages

object Money { implicit def doubleConverter(d: Double) = new { def EUR = { new Money(d, Euro) }

def USD = { new Money(d, Dollar) }}

No problem!

Page 46: A First Date With Scala

http://www.francolombardo.net

Domain Specific Languages

object Playground extends BasicClass { def main(args: Array[String]) { 10 PRINT "SCALA ROCKS!" 20 GOTO 10 RUN }}

With these tools we can write very exciting DSLs!

Example created by Szymon Jachim

See http://www.scala-lang.org/node/1403