SlideShare una empresa de Scribd logo
1 de 99
The Joy of
Maxim Novak
@maximnovakmaximn@wix.com https://github.com/maximn
Or : Why I love Scala
The Joy of
Maxim Novak
@maximnovakmaximn@wix.com https://github.com/maximn
Or : Why I love Scala
Hi
I’m Maxim Novak.
• Working on Wix’s back-end
• 9 years in the software industry
• 3 years avid Scala advocate
Scala is the better Java.
Scala is the better Java.
Simple concepts
Big impact
Why I Scala
Conciseness
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> products) {
double total = 0.0;
for (Product product : products) {
total += product.getPrice();
}
return total * tax;
}
}
Java (7) Checkout class
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax;
}
}
Java (8) Checkout class
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax;
}
}
Public by default
Public by default
class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax;
}
}
class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax;
}
}
No need for semi-colons
No need for semi-colons
class Checkout {
private double tax
public Checkout(double tax) {
this.tax = tax
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
class Checkout {
private double tax
public Checkout(double tax) {
this.tax = tax
}
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
Concise constructor and fields
Concise constructor and fields
class Checkout(tax: Double) {
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
class Checkout(tax: Double) {
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
Return last statement by default
Return last statement by default
class Checkout(tax: Double) {
double total(final List<Product> products) {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
class Checkout(tax: Double) {
double total(final List<Product> products) {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
Method arguments are final by default
And the Name comes before the Type
Method arguments are final by default
And the Name comes before the Type
class Checkout(tax: Double) {
def total(products: Seq[Product]): Double = {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
class Checkout(tax: Double) {
def total(products: Seq[Product]): Double = {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
Type Inference
Type Inference
class Checkout(tax: Double) {
def total(products: Seq[Product]) = {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
class Checkout(tax: Double) {
def total(products: Seq[Product]) = {
products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax
}
}
Remove more boilerplate
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum * tax
}
P P P P 1 3 7 4 15
.map(_.getPrice) .sum
Remove more boilerplate
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum
* tax
}
Scala
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product>
products) {
return products
.stream()
.mapToDouble(Product::getPrice)
.sum() * tax;
}
}
Java
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum
* tax
}
Scala
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
Java
Immutable by default
Easier to use = always thread safe = testable
Immutable by default
Prefer vals, immutable objects, and methods without side effects.
Reach for them first.
Use vars, mutable objects, and methods with side effects when
you have a specific need and justification for them.
- Programming in Scala By Martin Odersky, Lex Spoon, Bill Venners
“
”
http://www.yegor256.com/2014/06/0
9/objects-should-be-immutable.html
Easier to use = always thread safe = testable
Immutability
Set<Date> set = new HashSet<>();
Date date = new Date(2);
set.add(date);
date.setTime(4);
System.out.println(set.contains(date));
Easier to use = always thread safe = testable
http://www.yegor256.com/2014/06/09/
objects-should-be-immutable.html
HashCode Object
1
2
3
4
...
...
n
date
date
Domain Objects
public class Product {
public Product(String name, double price) {
this.name = name;
this.price = price;
}
private String name;
private double price;
public double getPrice() {
return price;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Product{" +
"name='" + name + ''' +
", price=" + price +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
Product product = (Product) o;
if (Double.compare(product.price, price) != 0)
return false;
return name != null ?
name.equals(product.name) : product.name ==
null;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(price);
result = (int) (temp ^ (temp >>> 32));
result = 31 * result + (name != null ?
name.hashCode() : 0);
return result;
}
}
public void setPrice(double price) {
this.price = price;
}
public void setName(String name) {
this.name = name;
}
Case Classes
case class Product(name: String, price: Double)
Less code = Less bugs = Readable code = Easier to maintain
Indeed, the ratio of time spent reading versus writing is well over 10 to 1.
We are constantly reading old code as part of the effort to write new code.
...[Therefore,] making it easy to read makes it easier to write.
- Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
“
”
Case Classes
case class Product(name: String, price: Double)
What else?
val book = Product("Book", 42)
val discountedBook = book.copy(price = 32)
Static Types Inference
Promotes better naming over type declaration
val i = 8
val s = "bar"
val withExplicitType: String = "baz"
val product = new Product(“name", 18)
val seq = Seq(1, 2, 3)
val withExplicitType: String = 8
Error:(4, 34) type mismatch;
found : Int(8)
required: String
val withExplicitType: String = 8
Static Types Inference
Promotes better naming over type declaration
val i = 8
val s = "bar"
val withExplicitType: String = "baz"
val product = new Product(“name", 18)
val seq = Seq(1, 2, 3)
def withString(s: String) = …
withString(i)
Error:(29, 16) type mismatch;
found : Int
required: String
withString(i)
^
private def add(a: Int, b: Int) = a + b
def add(a: Int, b: Int): Int = a + b
Static Types Inference
Promotes better naming over type declaration
Clarity &
Comprehension
Why I Scala
1. Use types to understand functions
interface Calculator {
Double divideOneBy(Integer divisor)
}
calculator.divideOneBy(0);
null ArithmeticException Double.NaN
What’s the result ?
Meet Scala Options
A better way for handling NULLs
Option [ T ]
None Some [ T ]
trait Calculator {
def divideOneBy(i: Int): Option[Double]
}
calculator.divideOneBy(0) == None
calculator.divideOneBy(2) == Some(0.5)
Meet Scala Options
A better way for handling NULLs
Meet Scala Options
val result: Option[Double]=calculator.divideOneBy(...)
var halfResult: Double = null
if (result.isDefined) {
halfResult = result.get / 2
}
else { ??? }
Imperative Style
val result: Option[Double] = calculator.divideOneBy(...)
val halfResult = result.map(r => r / 2)
Meet Scala Options
Functional style
val result: Option[Double] = calculator.divideOneBy(...)
val halfResult = result.map(_ / 2)
Meet Scala Options
Functional style
val productPhotoUrl: Option[String] = ...
val photoUrl: String =
productPhotoUrl.getOrElse("http://site.com/defaultProductImage.jpg")
Meet Scala Options
Default Values
What You Can Do with Options
val default: Option[String] = ...
val fallback: Option[String] = ...
val url = default.orElse(fallback)
Fallback
Java Libraries
Working with Java? Just wrap it with an Option
Option(null) == None
Option(obj) == Some(obj)
def javaApi(): SomeType = ...
val result = Option(javaApi())
NullPointerException – Never Again
Java Libraries
Working with Java? Just wrap it with an Option
Meet Scala’s Try
The flow is clear when it comes to Exceptions
Try [ T ]
Failure Success [ T ]
Why I Scala
1. Use types to understand functions
2. Elegant flow
For Comprehension
case class Photo(url: String)
case class Product(name: String, photo: Photo)
def photoUrl(product: Product) = {
var url: String = null
if (product != null) {
if (product.photo != null) {
if (product.photo.url != null) {
url = product.photo.url
}
}
}
url
}
case class Photo(url: String)
case class Product(name: String, photo: Photo)
def photoUrl(product: Product) = {
var url: String = null
if (product != null) {
if (product.photo != null) {
if (product.photo.url != null) {
url = product.photo.url
}
}
} url
}
case class Photo(url: Option[String])
case class Product(name: String, photo: Option[Photo])
def photoUrl(productOpt: Option[Product]) =
for {
product <- productOpt
photo <- product.photo
url <- photo.url
} yield url
Why I Scala
1. Use types to understand functions
2. Elegant flow
3. Powerful Pattern matching
Pattern Matching
A more powerful switch/case
val x: Any = ...
x match {
case 1 => "It's an integer 1"
case "1" => "It's a String "1""
case b: Boolean => "It's the a boolean : " + b.toString
case i: Int if i > 0 => "It's a positive Integer : " + i
case _: String => "It's a String, don’t care the value"
case _: Float | _: Double => "Something numeric"
case _ => "Didn't match any condition"
}
val obj: AnyRef = ...
obj match {
case Product(_, 0) =>
println("FREE! Don’t care about the name")
case Product(name, price) =>
println(name + " cost" + price)
}
Pattern Matching
Extracting Case-Classes
case class Product(name: String, price: Double)
val url: java.net.URL = ...
url match {
case HTTP(address) => "HTTP! It’s : " + address
case _ => "Unknown protocol"
}
object HTTP {
def unapply(url: URL): Option[String] =
if (url.getProtocol == "http") Some(url.toString)
else None
}
Custom Extractors
Make your code cleaner by extracting the how to’s
val url: java.net.URL = ...
url match {
case HTTP(address) => "HTTP! It’s : " + address
case FTP(address) => "FTP! It’s : " + address
case File(path) => "File! It’s : " + path
case CustomProtocol(foo, bar) =>
"Custom! It’s : " + foo + "/" + bar
case _ => "Unknown protocol"
}
Custom Extractors
Make your code cleaner by extracting the how to’s
Why I Scala
1. Use types to understand functions
2. Elegant flow
3. Powerful Pattern matching
4. Awesome Parameters
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}
}
Constructor overloading
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}
public DatabaseConnection(String host,
Credentials credentials) {
this(host, 3306, credentials); }
}
Constructor overloading
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}
public DatabaseConnection(String host,
Credentials credentials) {
this(host, 3306, credentials); }
public DatabaseConnection(Credentials credentials) {
this("localhost", credentials); }
}
Constructor overloading
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}
public DatabaseConnection(String host,
Credentials credentials) {
this(host, 3306, credentials); }
public DatabaseConnection(Credentials credentials) {
this("localhost", credentials); }
public DatabaseConnection() { this(Credentials.empty); }
}
Constructor overloading
Default Parameters
class DatabaseConnectionBuilder {
private String host = "localhost";
private int port = 3306;
private Credentials credentials = Credentials.empty
public DatabaseConnectionBuilder withHost(int port) {
this.host = host; return this; }
public DatabaseConnectionBuilder withPort(int port) {
this.port = port; return this; }
public DatabaseConnectionBuilder withCredentials(Credentials credentials) {
this.credentials = credentials; return this; }
public DatabaseConnection build() {
return new DatabaseConnection(host, port, credentials);
}
}
Builder Pattern
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Credentials.empty)
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Credentials.empty)
new DatabaseConnection("otherhost.com")
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Credentials.empty)
new DatabaseConnection(port = 3030)
Named Parameters
new File(path).setExecutable(true, false)
Named Parameters
boolean executable = true;
boolean ownerOnly = false;
new File(path).setExecutable(executable, ownerOnly);
Named Parameters
new File(path).setExecutable(executable = true, ownerOnly = false)
Why I Scala
1. Use types to understand functions
2. Elegant flow
3. Powerful Pattern matching
4. Awesome Parameters
5. Easier Strings
String Interpolation
More readable, Use $ for variables
val name = "Max"
val lang = "Scala"
val desc = s"Hello $name. $lang is awesome!"
Hello Max. Scala is awesome!
Quotes & Multiline
More readable, Easier to implement
val withQuotes =
"""Now I can use "quotes" without escaping"""
val multiline =
"""{
"firstName": "John",
"lastName": "Smith",
"age": 25
}"""
Why I Scala
1. Use types to understand functions
2. Elegant flow
3. Powerful Pattern matching
4. Awesome Parameters
5. Easier Strings
6. DSLs
Implicit Classes (extension methods)
import java.io.File
implicit class FileOps(val file: File) extends AnyVal {
...
def isClass: Boolean = file.isFile &&
file.getName.endsWith(".class")
...
}
Implicit Classes (extension methods)
import scala.tools.nsc.classpath.FileUtils.FileOps
val f = new File(...)
val isClass = f.isClass
Implicit Classes (extension methods)
Implicit Classes (extension methods)
1.to(10)
Range.Inclusive(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Infix Notation
String c = "foo".concat("bar");
String p = "foo" + "bar";
Infix Notation
val c = "foo" concat "bar"
“The binary operation E op E` is always interpreted as the
method call E.op(E`) “
-- Martin Odersky (Scala By Example)
https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/ScalaByExample.pdf
Implicit Classes & Infix Notation
1 to 10
for (i <- 1 to 10) {
...
}
DSL Made Easy
specs2 example
class SampleTest extends Specification {
"The 'Hello world' string" should {
"contain 11 characters" >> {
"Hello world" must haveSize(11)
}
}
}
DSL Made Easy
specs2 example
FUN & PROFIT
http://stackoverflow.com/research/developer-survey-2016
FUN & PROFIT
http://stackoverflow.com/research/developer-survey-2016
First Steps
You’re not alone
Adopted by:
… and a rapidly growing community
Migrating from Java
You can do it! Things working for you:
EASY to start
Migrating from Java
You can do it! Things working for you:
All Java libraries that you know and love
work in Scala too
Migrating from Java
You can do it! Things working for you:
You can start imperative and
move to functional, decide
where you want to be
Migrating from Java
There are caveats. Things working against you:
(Too much?) freedom
in programming style
http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html
Migrating from Java
There are caveats. Things working against you:
Slower
compile time
Migrating from Java
There are caveats. Things working against you:
Less tooling
Migrating from Java
There are caveats. Things working against you:
Recruiting
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaConversions._
Step 4
@BeanProperty
Annotation
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaConversions._
Step 4
@BeanProperty
Annotation
Step 5
Preserve Git
history
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaConversions._
Step 4
@BeanProperty
Annotation
Step 5
Preserve Git
history
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaConversions._
Step 4
@BeanProperty
Annotation
Step 5
Preserve Git
history
Wanna Learn More?
https://twitter.github.io/scala_school/
http://danielwestheide.com/scala/neophytes.html
http://twitter.github.io/effectivescala/
https://www.scala-exercises.org/std_lib/asserts
Advanced Topics
• Multiple inheritance
• Implicits
• Macros
• Functional libraries
Thank You!
Any Questions?
Maxim Novak
@maximnovakmaximn@wix.com https://github.com/maximn

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Scala Intro
Scala IntroScala Intro
Scala Intro
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
Selenium-Locators
Selenium-LocatorsSelenium-Locators
Selenium-Locators
 
The New JavaScript: ES6
The New JavaScript: ES6The New JavaScript: ES6
The New JavaScript: ES6
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentation
 
Hibernate ppt
Hibernate pptHibernate ppt
Hibernate ppt
 
Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I
 
Hibernate presentation
Hibernate presentationHibernate presentation
Hibernate presentation
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Core java Essentials
Core java EssentialsCore java Essentials
Core java Essentials
 
Collections and generics
Collections and genericsCollections and generics
Collections and generics
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
Python unit testing
Python unit testingPython unit testing
Python unit testing
 
Basics of JavaScript
Basics of JavaScriptBasics of JavaScript
Basics of JavaScript
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
Angular
AngularAngular
Angular
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 

Similar a Joy of scala

Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional ProgrammingLuka Jacobowitz
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202Mahmoud Samir Fayed
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?Federico Tomassetti
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java DevelopersYakov Fain
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for KotlinTechMagic
 
Introducing the ZIO DynamoDB Type Safe API
Introducing the ZIO DynamoDB Type Safe APIIntroducing the ZIO DynamoDB Type Safe API
Introducing the ZIO DynamoDB Type Safe APIAvinderBahra
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScriptChengHui Weng
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative FunctorsDavid Galichet
 
Refactoring - improving the smell of your code
Refactoring - improving the smell of your codeRefactoring - improving the smell of your code
Refactoring - improving the smell of your codevmandrychenko
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Naresha K
 
Scala+swing
Scala+swingScala+swing
Scala+swingperneto
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
The Ring programming language version 1.5.2 book - Part 7 of 181
The Ring programming language version 1.5.2 book - Part 7 of 181The Ring programming language version 1.5.2 book - Part 7 of 181
The Ring programming language version 1.5.2 book - Part 7 of 181Mahmoud Samir Fayed
 

Similar a Joy of scala (20)

Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
SCALA - Functional domain
SCALA -  Functional domainSCALA -  Functional domain
SCALA - Functional domain
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Java 102
Java 102Java 102
Java 102
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for Kotlin
 
Introducing the ZIO DynamoDB Type Safe API
Introducing the ZIO DynamoDB Type Safe APIIntroducing the ZIO DynamoDB Type Safe API
Introducing the ZIO DynamoDB Type Safe API
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
 
Refactoring - improving the smell of your code
Refactoring - improving the smell of your codeRefactoring - improving the smell of your code
Refactoring - improving the smell of your code
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
 
Scala+swing
Scala+swingScala+swing
Scala+swing
 
Kitura Todolist tutorial
Kitura Todolist tutorialKitura Todolist tutorial
Kitura Todolist tutorial
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
The Ring programming language version 1.5.2 book - Part 7 of 181
The Ring programming language version 1.5.2 book - Part 7 of 181The Ring programming language version 1.5.2 book - Part 7 of 181
The Ring programming language version 1.5.2 book - Part 7 of 181
 

Último

What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 

Último (20)

What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 

Joy of scala

  • 1. The Joy of Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn Or : Why I love Scala
  • 2. The Joy of Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn Or : Why I love Scala
  • 3. Hi I’m Maxim Novak. • Working on Wix’s back-end • 9 years in the software industry • 3 years avid Scala advocate
  • 4. Scala is the better Java.
  • 5. Scala is the better Java.
  • 8. public class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { double total = 0.0; for (Product product : products) { total += product.getPrice(); } return total * tax; } } Java (7) Checkout class
  • 9. public class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax; } } Java (8) Checkout class
  • 10. public class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax; } } Public by default
  • 11. Public by default class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax; } }
  • 12. class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax; } } No need for semi-colons
  • 13. No need for semi-colons class Checkout { private double tax public Checkout(double tax) { this.tax = tax } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  • 14. class Checkout { private double tax public Checkout(double tax) { this.tax = tax } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Concise constructor and fields
  • 15. Concise constructor and fields class Checkout(tax: Double) { double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  • 16. class Checkout(tax: Double) { double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Return last statement by default
  • 17. Return last statement by default class Checkout(tax: Double) { double total(final List<Product> products) { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  • 18. class Checkout(tax: Double) { double total(final List<Product> products) { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Method arguments are final by default And the Name comes before the Type
  • 19. Method arguments are final by default And the Name comes before the Type class Checkout(tax: Double) { def total(products: Seq[Product]): Double = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  • 20. class Checkout(tax: Double) { def total(products: Seq[Product]): Double = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Type Inference
  • 21. Type Inference class Checkout(tax: Double) { def total(products: Seq[Product]) = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  • 22. class Checkout(tax: Double) { def total(products: Seq[Product]) = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Remove more boilerplate
  • 23. class Checkout(tax: Double) { def total(products: Seq[Product]) = products.map(_.getPrice).sum * tax } P P P P 1 3 7 4 15 .map(_.getPrice) .sum Remove more boilerplate
  • 24. class Checkout(tax: Double) { def total(products: Seq[Product]) = products.map(_.getPrice).sum * tax } Scala public class Checkout { private double tax; public Checkout(double tax) { this.tax = tax; } double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax; } } Java
  • 25. class Checkout(tax: Double) { def total(products: Seq[Product]) = products.map(_.getPrice).sum * tax } Scala public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World"); } } Java
  • 26. Immutable by default Easier to use = always thread safe = testable
  • 27. Immutable by default Prefer vals, immutable objects, and methods without side effects. Reach for them first. Use vars, mutable objects, and methods with side effects when you have a specific need and justification for them. - Programming in Scala By Martin Odersky, Lex Spoon, Bill Venners “ ” http://www.yegor256.com/2014/06/0 9/objects-should-be-immutable.html Easier to use = always thread safe = testable
  • 28. Immutability Set<Date> set = new HashSet<>(); Date date = new Date(2); set.add(date); date.setTime(4); System.out.println(set.contains(date)); Easier to use = always thread safe = testable http://www.yegor256.com/2014/06/09/ objects-should-be-immutable.html HashCode Object 1 2 3 4 ... ... n date date
  • 30. public class Product { public Product(String name, double price) { this.name = name; this.price = price; } private String name; private double price; public double getPrice() { return price; } public String getName() { return name; } @Override public String toString() { return "Product{" + "name='" + name + ''' + ", price=" + price + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Product product = (Product) o; if (Double.compare(product.price, price) != 0) return false; return name != null ? name.equals(product.name) : product.name == null; } @Override public int hashCode() { int result; long temp; temp = Double.doubleToLongBits(price); result = (int) (temp ^ (temp >>> 32)); result = 31 * result + (name != null ? name.hashCode() : 0); return result; } } public void setPrice(double price) { this.price = price; } public void setName(String name) { this.name = name; }
  • 31. Case Classes case class Product(name: String, price: Double) Less code = Less bugs = Readable code = Easier to maintain Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. ...[Therefore,] making it easy to read makes it easier to write. - Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship “ ”
  • 32. Case Classes case class Product(name: String, price: Double) What else? val book = Product("Book", 42) val discountedBook = book.copy(price = 32)
  • 33. Static Types Inference Promotes better naming over type declaration val i = 8 val s = "bar" val withExplicitType: String = "baz" val product = new Product(“name", 18) val seq = Seq(1, 2, 3) val withExplicitType: String = 8 Error:(4, 34) type mismatch; found : Int(8) required: String val withExplicitType: String = 8
  • 34. Static Types Inference Promotes better naming over type declaration val i = 8 val s = "bar" val withExplicitType: String = "baz" val product = new Product(“name", 18) val seq = Seq(1, 2, 3) def withString(s: String) = … withString(i) Error:(29, 16) type mismatch; found : Int required: String withString(i) ^
  • 35. private def add(a: Int, b: Int) = a + b def add(a: Int, b: Int): Int = a + b Static Types Inference Promotes better naming over type declaration
  • 37. Why I Scala 1. Use types to understand functions
  • 38. interface Calculator { Double divideOneBy(Integer divisor) } calculator.divideOneBy(0); null ArithmeticException Double.NaN What’s the result ?
  • 39. Meet Scala Options A better way for handling NULLs Option [ T ] None Some [ T ]
  • 40. trait Calculator { def divideOneBy(i: Int): Option[Double] } calculator.divideOneBy(0) == None calculator.divideOneBy(2) == Some(0.5) Meet Scala Options A better way for handling NULLs
  • 41. Meet Scala Options val result: Option[Double]=calculator.divideOneBy(...) var halfResult: Double = null if (result.isDefined) { halfResult = result.get / 2 } else { ??? } Imperative Style
  • 42. val result: Option[Double] = calculator.divideOneBy(...) val halfResult = result.map(r => r / 2) Meet Scala Options Functional style
  • 43. val result: Option[Double] = calculator.divideOneBy(...) val halfResult = result.map(_ / 2) Meet Scala Options Functional style
  • 44. val productPhotoUrl: Option[String] = ... val photoUrl: String = productPhotoUrl.getOrElse("http://site.com/defaultProductImage.jpg") Meet Scala Options Default Values
  • 45. What You Can Do with Options val default: Option[String] = ... val fallback: Option[String] = ... val url = default.orElse(fallback) Fallback
  • 46. Java Libraries Working with Java? Just wrap it with an Option Option(null) == None Option(obj) == Some(obj)
  • 47. def javaApi(): SomeType = ... val result = Option(javaApi()) NullPointerException – Never Again Java Libraries Working with Java? Just wrap it with an Option
  • 48. Meet Scala’s Try The flow is clear when it comes to Exceptions Try [ T ] Failure Success [ T ]
  • 49. Why I Scala 1. Use types to understand functions 2. Elegant flow
  • 50. For Comprehension case class Photo(url: String) case class Product(name: String, photo: Photo) def photoUrl(product: Product) = { var url: String = null if (product != null) { if (product.photo != null) { if (product.photo.url != null) { url = product.photo.url } } } url }
  • 51. case class Photo(url: String) case class Product(name: String, photo: Photo) def photoUrl(product: Product) = { var url: String = null if (product != null) { if (product.photo != null) { if (product.photo.url != null) { url = product.photo.url } } } url } case class Photo(url: Option[String]) case class Product(name: String, photo: Option[Photo]) def photoUrl(productOpt: Option[Product]) = for { product <- productOpt photo <- product.photo url <- photo.url } yield url
  • 52. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching
  • 53. Pattern Matching A more powerful switch/case val x: Any = ... x match { case 1 => "It's an integer 1" case "1" => "It's a String "1"" case b: Boolean => "It's the a boolean : " + b.toString case i: Int if i > 0 => "It's a positive Integer : " + i case _: String => "It's a String, don’t care the value" case _: Float | _: Double => "Something numeric" case _ => "Didn't match any condition" }
  • 54. val obj: AnyRef = ... obj match { case Product(_, 0) => println("FREE! Don’t care about the name") case Product(name, price) => println(name + " cost" + price) } Pattern Matching Extracting Case-Classes case class Product(name: String, price: Double)
  • 55. val url: java.net.URL = ... url match { case HTTP(address) => "HTTP! It’s : " + address case _ => "Unknown protocol" } object HTTP { def unapply(url: URL): Option[String] = if (url.getProtocol == "http") Some(url.toString) else None } Custom Extractors Make your code cleaner by extracting the how to’s
  • 56. val url: java.net.URL = ... url match { case HTTP(address) => "HTTP! It’s : " + address case FTP(address) => "FTP! It’s : " + address case File(path) => "File! It’s : " + path case CustomProtocol(foo, bar) => "Custom! It’s : " + foo + "/" + bar case _ => "Unknown protocol" } Custom Extractors Make your code cleaner by extracting the how to’s
  • 57. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching 4. Awesome Parameters
  • 58. Default Parameters class DatabaseConnection { public DatabaseConnection(String host, int port, Credentials credentials) {} } Constructor overloading
  • 59. Default Parameters class DatabaseConnection { public DatabaseConnection(String host, int port, Credentials credentials) {} public DatabaseConnection(String host, Credentials credentials) { this(host, 3306, credentials); } } Constructor overloading
  • 60. Default Parameters class DatabaseConnection { public DatabaseConnection(String host, int port, Credentials credentials) {} public DatabaseConnection(String host, Credentials credentials) { this(host, 3306, credentials); } public DatabaseConnection(Credentials credentials) { this("localhost", credentials); } } Constructor overloading
  • 61. Default Parameters class DatabaseConnection { public DatabaseConnection(String host, int port, Credentials credentials) {} public DatabaseConnection(String host, Credentials credentials) { this(host, 3306, credentials); } public DatabaseConnection(Credentials credentials) { this("localhost", credentials); } public DatabaseConnection() { this(Credentials.empty); } } Constructor overloading
  • 62. Default Parameters class DatabaseConnectionBuilder { private String host = "localhost"; private int port = 3306; private Credentials credentials = Credentials.empty public DatabaseConnectionBuilder withHost(int port) { this.host = host; return this; } public DatabaseConnectionBuilder withPort(int port) { this.port = port; return this; } public DatabaseConnectionBuilder withCredentials(Credentials credentials) { this.credentials = credentials; return this; } public DatabaseConnection build() { return new DatabaseConnection(host, port, credentials); } } Builder Pattern
  • 63. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty)
  • 64. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty) new DatabaseConnection("otherhost.com")
  • 65. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty) new DatabaseConnection(port = 3030)
  • 67. Named Parameters boolean executable = true; boolean ownerOnly = false; new File(path).setExecutable(executable, ownerOnly);
  • 69. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching 4. Awesome Parameters 5. Easier Strings
  • 70. String Interpolation More readable, Use $ for variables val name = "Max" val lang = "Scala" val desc = s"Hello $name. $lang is awesome!" Hello Max. Scala is awesome!
  • 71. Quotes & Multiline More readable, Easier to implement val withQuotes = """Now I can use "quotes" without escaping""" val multiline = """{ "firstName": "John", "lastName": "Smith", "age": 25 }"""
  • 72. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching 4. Awesome Parameters 5. Easier Strings 6. DSLs
  • 73. Implicit Classes (extension methods) import java.io.File implicit class FileOps(val file: File) extends AnyVal { ... def isClass: Boolean = file.isFile && file.getName.endsWith(".class") ... }
  • 74. Implicit Classes (extension methods) import scala.tools.nsc.classpath.FileUtils.FileOps val f = new File(...) val isClass = f.isClass
  • 76. Implicit Classes (extension methods) 1.to(10) Range.Inclusive(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  • 77. Infix Notation String c = "foo".concat("bar"); String p = "foo" + "bar";
  • 78. Infix Notation val c = "foo" concat "bar" “The binary operation E op E` is always interpreted as the method call E.op(E`) “ -- Martin Odersky (Scala By Example) https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/ScalaByExample.pdf
  • 79. Implicit Classes & Infix Notation 1 to 10 for (i <- 1 to 10) { ... }
  • 80. DSL Made Easy specs2 example class SampleTest extends Specification { "The 'Hello world' string" should { "contain 11 characters" >> { "Hello world" must haveSize(11) } } }
  • 85. You’re not alone Adopted by: … and a rapidly growing community
  • 86. Migrating from Java You can do it! Things working for you: EASY to start
  • 87. Migrating from Java You can do it! Things working for you: All Java libraries that you know and love work in Scala too
  • 88. Migrating from Java You can do it! Things working for you: You can start imperative and move to functional, decide where you want to be
  • 89. Migrating from Java There are caveats. Things working against you: (Too much?) freedom in programming style http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html
  • 90. Migrating from Java There are caveats. Things working against you: Slower compile time
  • 91. Migrating from Java There are caveats. Things working against you: Less tooling
  • 92. Migrating from Java There are caveats. Things working against you: Recruiting
  • 93. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor
  • 94. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor Step 3 scala.collections. JavaConversions._ Step 4 @BeanProperty Annotation
  • 95. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor Step 3 scala.collections. JavaConversions._ Step 4 @BeanProperty Annotation Step 5 Preserve Git history
  • 96. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor Step 3 scala.collections. JavaConversions._ Step 4 @BeanProperty Annotation Step 5 Preserve Git history
  • 97. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor Step 3 scala.collections. JavaConversions._ Step 4 @BeanProperty Annotation Step 5 Preserve Git history
  • 99. Thank You! Any Questions? Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn

Notas del editor

  1. Hi, good afternoon! Today you’ll get introduced to Scala, and I’ll explain to you why I think that it’s an awesome language. You really should follow this talk, because, seriously, it can really change your professional career. After this talk you’ll think yourself - how did I spend all these years writing Java. And even in the rare case that you won’t move to Scala it might change the way you think about your Java code anyway. Just to get to know you - Who already played with Scala?
  2. My name is Maxim Novak. I’m in the software industry more than 9 years. Around 3 years ago I’ve joined Wix and since then I’m an avid Scala advocate. In Wix we use Scala as our main language for backend development. Today, I’ll share with you my experience with Scala and why I think that you should move.
  3. So what’s Scala? Why do we actually need it? And why is it called the better Java? It’s another programming language that works on the JVM. It’s a modern language with many features that help to our productivity as developers We enjoy from the rich and proven JVM ecosystem which includes tools, libraries, and reliable runtime I believe that by the end of this session you’ll be convinced that you should at least give it a try. ...
  4. This session will have 2 parts. In the first part I’ll tell you about the benefits of Scala and why do I think that it’s the best programming language in terms of developer productivity. In the second part we’ll talk about how do we move to Scala from Java or any other(JVM/Not) language. We’ll have some time for questions in the end, but if you feel that you need to ask something during the talk feel free to do ask.
  5. In this talk you’re going to see just a small portion of Scala’s features. We’ll cover some simple concepts that have a big impact on the way you develop software. In most of the samples today I’ll show a comparison between Java to Scala code.
  6. So we’ll start with conciseness. To get some feeling of the language we’ll start with a Java sample and convert it to Scala step-by-step. Java is great language, but the problem with it - tons of boilerplate and ceremony. Scala help us with this matter. You concentrate on solving a business problem most of your time instead of just typing. Let’s start with an example.
  7. We see a `Checkout` class. It’s pretty straightforward, get a tax in the constructor and can calculate the price for a products list. This is how it looks with Java7. I show you this because, there’s still a lot of Java7 code and many of us need to work with Java7 codebase. (45.5% as to 2016, same for java8, 9% java 6 - ohh .. these poor people) Who works on the JVM? Who uses Java8? When Java8 released some people said - now we don’t need Scala, Java8 solve the problems for us. So we’ll transform this code to Java8 and then to Scala to see the gain of each change. Few words about Java8 - it proves that Scala goes in the correct direction.
  8. This sample does the same as the prev, but Java8. As you can see, the change is not dramatic. We can see the functional style of the total method (kind of similar to Scala). Let’s start converting it to Scala
  9. In Java the default access modifier is `package-private`, so in many of our classes we explicitly need to declare that they’re public. In Scala the default is public.
  10. We don’t really need the semicolon in end of any line. In Scala the compiler is smart enough to understand. It uses a look ahead technique to understand the meaning on a new-line. Actually you can keep it, sometimes new Java developers do, but there’s really no need.
  11. The constructor and the field. All what we want to say here that we want to save the tax as a class member. A lot of boilerplate.
  12. Another thing is the `return`. Also not necessary. You can use it but really no need to. The last line will be used as the return value.
  13. In java it’s considered as a bad practice to change the value of a parameter, so we can say `final`, but we don’t want to do it for all of our parameters. If we change it we’ll get a compilation warning. Therefore, in Scala it’s the default.
  14. Moreover, we can see that we switched the order of the variable type and the name. There’re 2 reasons - Scala consider the name as the more important part, so it’s first It goes easier with `type inference` which we’ll see soon.
  15. The compiler can understand that we’re summing a Seq on doubles and multiply it by a double so it can understand that the return type of this method is a double. So we can remove it as well.
  16. Even more boilerplate. We don’t care about the `stream` part. Just by coincidence the price is a double and we have `mapToDouble`, if it was `Dollar` or something else it would be harder.
  17. That’s how it will look in Scala! And I even have a cool animation here
  18. Let’s see side-by-side comparison. Anyone still not convinced?
  19. Come on! It’s the same size of the java HelloWorld.
  20. In imperative language like Java a computation is usually done by mutating variables and this way progress with the computation. On the other hand functional programming have pure functions that get input and return output without mutating variables. The functional way in many cases is cleaner and simple. So immutability fits well with functional programming style. ...
  21. Why most people write mutable code in Java? Because this is the default and developers usually will do the default. When using less mutable state and more functional style Easier to read/understand/reason about the code (predictable, local reasoning) Reduce bugs Easier to test Behaves better in multithreaded environment. And yes, you can do it in Java, but in Scala it’s much easier, and that’s the default.
  22. You want to see real life example, right Just to illustrate how easily mutable state can cause bugs. And this is a very simple example, even not multi-threaded
  23. Domain objects is something we create a lot. Let’s see a Java sample.
  24. In this example we see a class that describes a Product. Mention that we don’t want setters Do you think that this is a reasonable amount of code for what we get? Would you be happy to write less code? What do you say about one line? So with Scala you can!
  25. This is how this looks with Scala! Now, you probably say actually no one really write this code, the IDE generate it for us. So in Java not only that we have a complicated language, now we need a complicated IDE to manage it. Quote by Uncle Bob - Most of the time we read code. We want our code to stay clean. In Scala the compiler generate all this boilerplate for us.
  26. You can create it without the `new` keyword, this is also reduce boilerplate and also cool because you can just pass it as a function. Another thing, because it’s immutable, we get the `copy` method on any case-class. This allows us to create new case-classes from existing ones. Extractors - We’ll talk about them later when we get to pattern matching
  27. With Scala you don’t have to declare the TYPE of the field. You can if you want to. We alrady saw this before, the order of the decleration (type/name) is reversed from Java. More emphasis on the name then on the type. It’s important to notice that the language is statically typed, so if we break the rules - we’ll get a compilation error.
  28. With Scala you don’t have to declare the TYPE of the field. You can if you want to. We alrady saw this before, the order of the decleration (type/name) is reversed from Java. More emphasis on the name then on the type. It’s important to notice that the language is statically typed, so if we break the rules - we’ll get a compilation error.
  29. Also works for methods. By convention usually we’ll declare the type in public methods to break in case of change in public API, but in private methods we’ll omit it to allow easier change.
  30. Now let’s see some more modern constructs that will help us to organize our code.
  31. In Java - we call a method. But we don’t really know what we get as a rusult.
  32. Let’s have a look at this Calculator example. What will happen when we run this code? The method signature states that it returns a Double but it lies. Actually, there are few options. We can read the documentation, or write a test that checks this code. using `null` as a result is a bad practice because many times bugs lead to nulls so when we have it we don’t know if it’s intended null or because of a bug ArithmeticException is unchecked so the caller can’t know it might be thrown. In scala we’ll usually solve this problem in the type system level.
  33. Option is a container type that can contain a value or be empty. For example, in our calculator example a result when a function is undefined.
  34. So let’s change the signature of the function and now it’ll return Option[Double]
  35. Now how we work with this Option? We can do it in imperative style like Java.
  36. Or we can go a bit more functional. .map works on an Option exactly like a collection with one element or empty. Also note that we don’t have the mutable state anymore.
  37. You can do it even shorter.
  38. In addition, we have more goodies that help us to work with Option. For example - default values.
  39. Fallback value
  40. What about existing Java codebase that can return `null`? Easily just wrap it with option.
  41. Just wrap your APIs that can return null with Option. And you’ll never see a NPE anymore
  42. Try is very similar to Option. It’s also a container type that can hold a successfull result or a Failure with a Throwable. It works very similar to Option so I’ll skip it in this talk.
  43. I assume that practically everyone in this room wrote a code like this one. Let’s convert the Optional parameters that can be null to an Option type. Then I’ll show you how you can benefit from a construct that’s called `for comprehension`.
  44. Instead of checking nulls and catching exceptions – options are defined. If they’re none we do something if they’re some we do something else.
  45. AnyRef is similar to a Java’s `Object`.
  46. If you’re working with a class that’s not a case-class, for example Java code. You can write your own extractor to any class.
  47. Then our code will look cleaner.
  48. Default parameters make our life much easier when we have to deal with many parameters
  49. In this example we’re looking at a DatabaseConnection sample class. So when we start, we make sure that the constructor get the needed parameters. But the we found out that in most cases we don’t change the port, so we decide to add another constructor.
  50. Let’s say it’s mysql so the default port is 3306. But then, we find out that usually we use ‘localhost’ as the host, so we add another one
  51. And again, we don’t want the credentials to be mandatory so we add another one
  52. But now, we have a new use case when we want to specify the host, but not the port. So in this case it’s doable because the host is a String but the port is an int, but if they both would be strings it’s getting complicated. So In java we have a solution for this.
  53. The builder pattern, but still that’s a lot of code to write. And the as the user of the class you need to know about the Builder to build the connection.
  54. In scala we can use default parameters to solve this problem. This DatabaseConnection class will look like this.
  55. We can use ordering
  56. Or naming.
  57. Named parameters have another advantage. This is Java’s File API. Who knows what’s the true, false means? So there’s a way to write it in a more readable way.
  58. Extract variables
  59. In Scala it’s even easier.
  60. Default parameters make our life much easier when we have to deal with many parameters
  61. Quotes and multiline
  62. Domain Specific Languages
  63. This example is taken from the source code of the Scala Compiler We can use `Implicit Class` to extend existing classes. In this case they extended the java File class and added to it 2 methods.
  64. To use it, all we need to do is make sure that we have this class in the scope and we can call them as they’re methods on this class. The IDE will signal to us that the method `isClass` is an extention
  65. The IDE is even powerful enough to find which `implicit class` we’re using here
  66. Using this, we can write something like this. This expression returns a class of type Range which is actually an `Iterable` Remember this example, we’ll get back to it shortly.
  67. We all know how we invoke a method on a class. For some operators we can do it a bit differently, although it’s actually the same thing. If you think about it. We’re invoking the `+` function on a class of type String and giving it another string as an parameter. In Java, actually the compiler is taking care of this + operator on the string, converts it to a StringBuilder and calls the .append method.
  68. So in Scala, we can do it with any method name. It’s perfectly fine. Odersky’s quote
  69. Now, let’s combine these two features. And a `for loop`, will look like this
  70. specs2 is a well known testing library in the Scala ecosystem. I want to show you the DSL they built to write tests. The added some methods on a `String` to let you do that. Also, look at the test itself, it also looks like English
  71. This is how it looks in the IDE when we run the tests. Finally we can have nice human readable tests descriptions easily
  72. So in addition to that I like Scala and I think that it’s awesome. It got pretty high score as a Loved language in stack-overfllow’s developers survery for 2016
  73. Also, at least in the US, it’s the most well paid language.
  74. OK, so we all convinced that it’s good for us, now let’s talk about how to we start.
  75. First of all you should know that you’re not alone. Many big companies already use this technology in production and the community is getting bigger and bigger all the time. So not only that it’s cool, we can definitely say that the technology is production prooven.
  76. If you’re a JVM shop, it’ll be very easy for you to move to Scala. You already have the runtime on your production servers, you can keep using your build tools, your IDE, benchmarking tools Basically you're already familiar with the tools you need.
  77. All the eco-system is available for us - all the JVM libraries.
  78. You can start writing imperative style (Jala), and gradually move to be more functional. It’s a hybrid imperative/functional language and you can choose the style. You can use concepts from both worlds of OOP and functional programming. You can start writing Jala in a matter of days/weeks. You can combine Scala classes together with Java classes in the same project. An important note for beginners, you don’t have to know everything, you can make a progress gradually. The move from Java can be incremental.
  79. If I’ll say that all is perfect, you probably won’t beliebe me. Not everything is perfect, and you should be aware of that. One big critisism of Scala is that it’s very easy to write code that is hard to read later. Too much freedom - but you’ll get used to write idiomatic Scala. I like this freedom, but you should be responsible. A rule that I always use is to use the most simple tools to solve your problem. Recommended blog post.
  80. Longer compilation time. Because the compiler is much more powerful and smart it takes longer to compile your code. This is improving all the time. In Wix we have microservices architecture so we have many small apps so the compilation time is not a problem for us. In larger apps it can get noticeable and annoying.
  81. Less tooling. There are many tools from the JVM world that you can use with Scala, but some tools still not complete. For example - the IDE (debug, refactor). Getting better all the time. Also cluttered stack traces.
  82. Because Scala cought popularity lately, it’s hard to find experienced Scala developers. In Wix we’re aiming to hire the best software engineers that can write any language and not a specific language software developer. The good software engineers will be happy to learn new exciting language and concepts. So this is even a kind of filter. Needless to say that it also have a cost of education and mentoring after the hire.
  83. So you’re in the Java world and you want to move to Scala, here are few tips that will help you to get started. Let’s go over the steps. If you don’t feel comfortable enough to write your production application in Scala you can start with the tests. Scala have few great testing frameworks like specs2 which we use at Wix and scala-test also good one. You can start writing new classes in Scala while old classes still in Java. IDE can convert to Jala, then refactor. This will make your classes much shorter and more readable.
  84. Yes, you see this correctly
  85. Just one click
  86. 3. Scala has its own collections library. To avoid the friction use Javaconversions 4. If you work with libraries that rely on getters/setters you can use @BeanPropery annotation. 5. Tip to save the history. Change the filename, commit, then change the content and commit again. ...
  87. To wrap up - we covered very briefly some of the basic concepts of Scala, why this is good for you and you got some tips to start using Scala. Hope that you all enjoyed and you already started planning the move :) Look, there’s a learning curve, but when you know it well you’re super productive - in orders of magnitude.
  88. Some extra materials