O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
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<Produc...
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Produc...
public class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Produc...
Public by default
class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final ...
class Checkout {
private double tax;
public Checkout(double tax) {
this.tax = tax;
}
double total(final List<Product> prod...
No need for semi-colons
class Checkout {
private double tax
public Checkout(double tax) {
this.tax = tax
}
double total(fi...
class Checkout {
private double tax
public Checkout(double tax) {
this.tax = tax
}
double total(final List<Product> produc...
Concise constructor and fields
class Checkout(tax: Double) {
double total(final List<Product> products) {
return products
...
class Checkout(tax: Double) {
double total(final List<Product> products) {
return products
.stream()
.mapToDouble(Product:...
Return last statement by default
class Checkout(tax: Double) {
double total(final List<Product> products) {
products
.stre...
class Checkout(tax: Double) {
double total(final List<Product> products) {
products
.stream()
.mapToDouble(Product::getPri...
Method arguments are final by default
And the Name comes before the Type
class Checkout(tax: Double) {
def total(products:...
class Checkout(tax: Double) {
def total(products: Seq[Product]): Double = {
products
.stream()
.mapToDouble(Product::getPr...
Type Inference
class Checkout(tax: Double) {
def total(products: Seq[Product]) = {
products
.stream()
.mapToDouble(Product...
class Checkout(tax: Double) {
def total(products: Seq[Product]) = {
products
.stream()
.mapToDouble(Product::getPrice)
.su...
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum * tax
}
P P P P 1 3 7 4 15
...
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum
* tax
}
Scala
public class ...
class Checkout(tax: Double) {
def total(products: Seq[Product]) =
products.map(_.getPrice).sum
* tax
}
Scala
public class ...
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, mut...
Immutability
Set<Date> set = new HashSet<>();
Date date = new Date(2);
set.add(date);
date.setTime(4);
System.out.println(...
Domain Objects
public class Product {
public Product(String name, double price) {
this.name = name;
this.price = price;
}
private String ...
Case Classes
case class Product(name: String, price: Double)
Less code = Less bugs = Readable code = Easier to maintain
In...
Case Classes
case class Product(name: String, price: Double)
What else?
val book = Product("Book", 42)
val discountedBook ...
Static Types Inference
Promotes better naming over type declaration
val i = 8
val s = "bar"
val withExplicitType: String =...
Static Types Inference
Promotes better naming over type declaration
val i = 8
val s = "bar"
val withExplicitType: String =...
private def add(a: Int, b: Int) = a + b
def add(a: Int, b: Int): Int = a + b
Static Types Inference
Promotes better naming...
Clarity &
Comprehension
Why I Scala
1. Use types to understand functions
interface Calculator {
Double divideOneBy(Integer divisor)
}
calculator.divideOneBy(0);
null ArithmeticException Double.Na...
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) =...
Meet Scala Options
val result: Option[Double]=calculator.divideOneBy(...)
var halfResult: Double = null
if (result.isDefin...
val result: Option[Double] = calculator.divideOneBy(...)
val halfResult = result.map(r => r / 2)
Meet Scala Options
Functi...
val result: Option[Double] = calculator.divideOneBy(...)
val halfResult = result.map(_ / 2)
Meet Scala Options
Functional ...
val productPhotoUrl: Option[String] = ...
val photoUrl: String =
productPhotoUrl.getOrElse("http://site.com/defaultProduct...
What You Can Do with Options
val default: Option[String] = ...
val fallback: Option[String] = ...
val url = default.orElse...
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 wit...
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: Produ...
case class Photo(url: String)
case class Product(name: String, photo: Photo)
def photoUrl(product: Product) = {
var url: S...
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 ...
val obj: AnyRef = ...
obj match {
case Product(_, 0) =>
println("FREE! Don’t care about the name")
case Product(name, pric...
val url: java.net.URL = ...
url match {
case HTTP(address) => "HTTP! It’s : " + address
case _ => "Unknown protocol"
}
obj...
val url: java.net.URL = ...
url match {
case HTTP(address) => "HTTP! It’s : " + address
case FTP(address) => "FTP! It’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) {}...
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}...
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}...
Default Parameters
class DatabaseConnection {
public DatabaseConnection(String host,
int port,
Credentials credentials) {}...
Default Parameters
class DatabaseConnectionBuilder {
private String host = "localhost";
private int port = 3306;
private C...
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Crede...
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Crede...
Default Parameters
class DatabaseConnection(host: String = "localhost",
port: Int = 3306,
credentials: Credentials = Crede...
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. Eas...
String Interpolation
More readable, Use $ for variables
val name = "Max"
val lang = "Scala"
val desc = s"Hello $name. $lan...
Quotes & Multiline
More readable, Easier to implement
val withQuotes =
"""Now I can use "quotes" without escaping"""
val m...
Why I Scala
1. Use types to understand functions
2. Elegant flow
3. Powerful Pattern matching
4. Awesome Parameters
5. Eas...
Implicit Classes (extension methods)
import java.io.File
implicit class FileOps(val file: File) extends AnyVal {
...
def i...
Implicit Classes (extension methods)
import scala.tools.nsc.classpath.FileUtils.FileOps
val f = new File(...)
val 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`) ...
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 char...
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 y...
Migrating from Java
There are caveats. Things working against you:
(Too much?) freedom
in programming style
http://www.lih...
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.
JavaCon...
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaCon...
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaCon...
Java
Step 1
Tests in Scala
Scala
Step 2
Convert class to JALA,
make it compile,
refactor
Step 3
scala.collections.
JavaCon...
Wanna Learn More?
https://twitter.github.io/scala_school/
http://danielwestheide.com/scala/neophytes.html
http://twitter.g...
Thank You!
Any Questions?
Maxim Novak
@maximnovakmaximn@wix.com https://github.com/maximn
Próximos SlideShares
Carregando em…5
×

Joy of scala

"The joy of Scala" - Maxim Novak / Wix

Around eight years ago I started my journey as a developer. Since then, I've played around with many languages and thought that C# offers the best developer productivity. After joining Wix two years ago, I was exposed to the amazing world of Scala and Functional Programming and never looked back.

In Scala the code is much more concise, less ceremonious, immutable by default, combines functional with object oriented, seamlessly interoperates with Java, and many software engineering patterns are already baked into the language. Most importantly - Scala is FUN! By the end of the session you too will, hopefully, convert to Scala and never look back.

Recording of the lecture (Hebrew) - https://youtu.be/TcnYTwff2xU

  • Entre para ver os comentários

Joy of scala

  1. 1. The Joy of Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn Or : Why I love Scala
  2. 2. The Joy of Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn Or : Why I love Scala
  3. 3. Hi I’m Maxim Novak. • Working on Wix’s back-end • 9 years in the software industry • 3 years avid Scala advocate
  4. 4. Scala is the better Java.
  5. 5. Scala is the better Java.
  6. 6. Simple concepts Big impact
  7. 7. Why I Scala Conciseness
  8. 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. 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. 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. 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. 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. 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. 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. 15. Concise constructor and fields class Checkout(tax: Double) { double total(final List<Product> products) { return products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  16. 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. 17. Return last statement by default class Checkout(tax: Double) { double total(final List<Product> products) { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  18. 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. 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. 20. class Checkout(tax: Double) { def total(products: Seq[Product]): Double = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Type Inference
  21. 21. Type Inference class Checkout(tax: Double) { def total(products: Seq[Product]) = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } }
  22. 22. class Checkout(tax: Double) { def total(products: Seq[Product]) = { products .stream() .mapToDouble(Product::getPrice) .sum() * tax } } Remove more boilerplate
  23. 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. 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. 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. 26. Immutable by default Easier to use = always thread safe = testable
  27. 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. 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
  29. 29. Domain Objects
  30. 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. 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. 32. Case Classes case class Product(name: String, price: Double) What else? val book = Product("Book", 42) val discountedBook = book.copy(price = 32)
  33. 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. 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. 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
  36. 36. Clarity & Comprehension
  37. 37. Why I Scala 1. Use types to understand functions
  38. 38. interface Calculator { Double divideOneBy(Integer divisor) } calculator.divideOneBy(0); null ArithmeticException Double.NaN What’s the result ?
  39. 39. Meet Scala Options A better way for handling NULLs Option [ T ] None Some [ T ]
  40. 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. 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. 42. val result: Option[Double] = calculator.divideOneBy(...) val halfResult = result.map(r => r / 2) Meet Scala Options Functional style
  43. 43. val result: Option[Double] = calculator.divideOneBy(...) val halfResult = result.map(_ / 2) Meet Scala Options Functional style
  44. 44. val productPhotoUrl: Option[String] = ... val photoUrl: String = productPhotoUrl.getOrElse("http://site.com/defaultProductImage.jpg") Meet Scala Options Default Values
  45. 45. What You Can Do with Options val default: Option[String] = ... val fallback: Option[String] = ... val url = default.orElse(fallback) Fallback
  46. 46. Java Libraries Working with Java? Just wrap it with an Option Option(null) == None Option(obj) == Some(obj)
  47. 47. def javaApi(): SomeType = ... val result = Option(javaApi()) NullPointerException – Never Again Java Libraries Working with Java? Just wrap it with an Option
  48. 48. Meet Scala’s Try The flow is clear when it comes to Exceptions Try [ T ] Failure Success [ T ]
  49. 49. Why I Scala 1. Use types to understand functions 2. Elegant flow
  50. 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. 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. 52. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching
  53. 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. 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. 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. 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. 57. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching 4. Awesome Parameters
  58. 58. Default Parameters class DatabaseConnection { public DatabaseConnection(String host, int port, Credentials credentials) {} } Constructor overloading
  59. 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. 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. 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. 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. 63. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty)
  64. 64. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty) new DatabaseConnection("otherhost.com")
  65. 65. Default Parameters class DatabaseConnection(host: String = "localhost", port: Int = 3306, credentials: Credentials = Credentials.empty) new DatabaseConnection(port = 3030)
  66. 66. Named Parameters new File(path).setExecutable(true, false)
  67. 67. Named Parameters boolean executable = true; boolean ownerOnly = false; new File(path).setExecutable(executable, ownerOnly);
  68. 68. Named Parameters new File(path).setExecutable(executable = true, ownerOnly = false)
  69. 69. Why I Scala 1. Use types to understand functions 2. Elegant flow 3. Powerful Pattern matching 4. Awesome Parameters 5. Easier Strings
  70. 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. 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. 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. 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. 74. Implicit Classes (extension methods) import scala.tools.nsc.classpath.FileUtils.FileOps val f = new File(...) val isClass = f.isClass
  75. 75. Implicit Classes (extension methods)
  76. 76. Implicit Classes (extension methods) 1.to(10) Range.Inclusive(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  77. 77. Infix Notation String c = "foo".concat("bar"); String p = "foo" + "bar";
  78. 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. 79. Implicit Classes & Infix Notation 1 to 10 for (i <- 1 to 10) { ... }
  80. 80. DSL Made Easy specs2 example class SampleTest extends Specification { "The 'Hello world' string" should { "contain 11 characters" >> { "Hello world" must haveSize(11) } } }
  81. 81. DSL Made Easy specs2 example
  82. 82. FUN & PROFIT http://stackoverflow.com/research/developer-survey-2016
  83. 83. FUN & PROFIT http://stackoverflow.com/research/developer-survey-2016
  84. 84. First Steps
  85. 85. You’re not alone Adopted by: … and a rapidly growing community
  86. 86. Migrating from Java You can do it! Things working for you: EASY to start
  87. 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. 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. 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. 90. Migrating from Java There are caveats. Things working against you: Slower compile time
  91. 91. Migrating from Java There are caveats. Things working against you: Less tooling
  92. 92. Migrating from Java There are caveats. Things working against you: Recruiting
  93. 93. Java Step 1 Tests in Scala Scala Step 2 Convert class to JALA, make it compile, refactor
  94. 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. 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. 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. 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
  98. 98. 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
  99. 99. Thank You! Any Questions? Maxim Novak @maximnovakmaximn@wix.com https://github.com/maximn

×