Java 8 and beyond, a scala story

78
Java 8 and Beyond, a Scala Story Ittai Zeidman, September 2016 http://searchengineland.com/figz/wp-content/seloads/2015/06/evolution-seo-marketer-ss- 1920.jpg

Transcript of Java 8 and beyond, a scala story

Page 1: Java 8 and beyond, a scala story

Java 8 and Beyond,a Scala StoryIttai Zeidman, September 2016http://searchengineland.com/figz/wp-content/seloads/2015/06/evolution-seo-marketer-ss-1920.jpg

Page 2: Java 8 and beyond, a scala story

Ittai Zeidman• @ittaiz• Backend Engineering Lead @

Wix• Clean Code Fanatic• Scala lover• Proud spouse and father of 3

Page 3: Java 8 and beyond, a scala story

Ittai Zeidman• @ittaiz• Backend Engineering Lead @

Wix• Clean Code Fanatic• Scala lover• Proud spouse and father of 3

Page 4: Java 8 and beyond, a scala story

Preface

Page 5: Java 8 and beyond, a scala story

Preface• Java 8 was

released in 2014

Page 6: Java 8 and beyond, a scala story

Preface• Java 8 was

released in 2014• Which begs the

question…• Is Scala still

relevant?

Page 7: Java 8 and beyond, a scala story

Preface• Java 8 was

released in 2014• Which begs the

question…• Is Scala still

relevant?– Yes.

Page 8: Java 8 and beyond, a scala story

Preface• Java 8 was

released in 2014• Which begs the

question…• Is Scala still

relevant?– Yes.

Page 9: Java 8 and beyond, a scala story

Preface• Java 8 was

released in 2014• Which begs the

question…• Is Scala still

relevant?– Yes.– This talk is about

convincing you!

Page 10: Java 8 and beyond, a scala story

Quick Agenda• A bit of history– The Java-Scala gap– How Java 8 reduces

it– Remaining gaps

• A deeper dive into:– Traits– Type Inference– Pattern matching– Implicits

Page 11: Java 8 and beyond, a scala story

The Java-Scala gap (pre Java 8)Scala’s big selling points:• Lambdas• Collections library• Traits• Type inference• DSLs• Implicits

Page 12: Java 8 and beyond, a scala story

The Java-Scala gap (currently)Scala’s big selling points:• Lambdas• Collections library• Traits• Type inference• DSLs• Implicits

Page 13: Java 8 and beyond, a scala story

There’s So Much More…

Page 14: Java 8 and beyond, a scala story

There’s So Much More…For-comprehensionsFlexible scopingBuilt-in tuplesHigher-kinded typesDeclaration-site variance

MacrosBottom typesStructural typesType membersPath-dependent typesImplicit conversions

Page 15: Java 8 and beyond, a scala story

RIGHT. WHY SHOULD YOU CARE?

Page 16: Java 8 and beyond, a scala story

#1: TRAITS

Page 17: Java 8 and beyond, a scala story

Ye Olde Loggingimport org.slf4j.Logger;import org.slf4j.LoggerFactory;

public class ClassWithLogs { private static Logger log = LoggerFactory.getLogger(ClassWithLogs.class);

public String getNormalizedName(Person person) { log.info("getNormalizedName called"); log.debug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); log.debug("Normalized name is: " + normalizedName); return normalizedName; }}

Page 18: Java 8 and beyond, a scala story

Ye Olde Loggingimport org.slf4j.Logger;import org.slf4j.LoggerFactory;

public class ClassWithLogs { private static Logger log = LoggerFactory.getLogger(ClassWithLogs.class);

public String getNormalizedName(Person person) { log.info("getNormalizedName called"); log.debug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); log.debug("Normalized name is: " + normalizedName); return normalizedName; }}

Boilerplate

Page 19: Java 8 and beyond, a scala story

Ye Olde Loggingimport org.slf4j.Logger;import org.slf4j.LoggerFactory;

public class ClassWithLogs { private static Logger log = LoggerFactory.getLogger(ClassWithLogs.class);

public String getNormalizedName(Person person) { log.info("getNormalizedName called"); log.debug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); log.debug("Normalized name is: " + normalizedName); return normalizedName; }}

Eager Evaluation

Boilerplate

Page 20: Java 8 and beyond, a scala story

Ye Olde Loggingimport org.slf4j.Logger;import org.slf4j.LoggerFactory;

public class ClassWithLogs { private static Logger log = LoggerFactory.getLogger(ClassWithLogs.class);

public String getNormalizedName(Person person) { log.info("getNormalizedName called"); log.debug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); log.debug("Normalized name is: " + normalizedName); return normalizedName; }}

Eager Evaluation

Boilerplate

Page 21: Java 8 and beyond, a scala story

Improvement?public class LoggingSample implements Logging {

public String getNormalizedName(Person person) { logInfo("getNormalizedName called"); logDebug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); logDebug("Normalized name is: " +

normalizedName); return normalizedName; }

}

Page 22: Java 8 and beyond, a scala story

Improvement?public class LoggingSample implements Logging {

public String getNormalizedName(Person person) { logInfo("getNormalizedName called"); logDebug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); logDebug("Normalized name is: " +

normalizedName); return normalizedName; }

}

Page 23: Java 8 and beyond, a scala story

Improvement?public class LoggingSample implements Logging {

public String getNormalizedName(Person person) { logInfo("getNormalizedName called"); logDebug("Normalizing " + person.toString()); String normalizedName = person.getName().toUpperCase().trim(); logDebug("Normalized name is: " +

normalizedName); return normalizedName; }

}

Page 24: Java 8 and beyond, a scala story

Java Interface Limitations

Page 25: Java 8 and beyond, a scala story

Java Interface Limitations

• No fields allowed

Page 26: Java 8 and beyond, a scala story

Java Interface Limitations

• No fields allowed– Need Logger

instance

Page 27: Java 8 and beyond, a scala story

Java Interface Limitations

• No fields allowed– Need Logger

instance– Workaround: getter

public interface Logging { Logger logger();

default void logDebug(String msg) { if (logger().isDebugEnabled()) logger().debug(msg); }

default void logInfo(String msg) { if (logger().isInfoEnabled()) logger().info(msg); }}

Page 28: Java 8 and beyond, a scala story

Java Interface Limitations

• No fields allowed– Need Logger

instance– Workaround: getter– But... boilerplate :-(

public interface Logging { Logger logger();

default void logDebug(String msg) { if (logger().isDebugEnabled()) logger().debug(msg); }

default void logInfo(String msg) { if (logger().isInfoEnabled()) logger().info(msg); }}

Page 29: Java 8 and beyond, a scala story

Java Interface Limitations

• No fields allowed– Need Logger

instance– Workaround: getter– But... boilerplate :-(

• Only public methods– Logging APIs visible!– … as is logger()

public interface Logging { Logger logger();

default void logDebug(String msg) { if (logger().isDebugEnabled()) logger().debug(msg); }

default void logInfo(String msg) { if (logger().isInfoEnabled()) logger().info(msg); }}

Page 30: Java 8 and beyond, a scala story

And Lazy Evaluation?

Page 31: Java 8 and beyond, a scala story

And Lazy Evaluation?• Can be implemented with a lambda:

import java.util.function.Supplier;

default void logDebug(Supplier<String> message) { if (getLogger().isDebugEnabled()) getLogger().debug(message.get());}

Page 32: Java 8 and beyond, a scala story

And Lazy Evaluation?• Can be implemented with a lambda:

import java.util.function.Supplier;

default void logDebug(Supplier<String> message) { if (getLogger().isDebugEnabled()) getLogger().debug(message.get());}

• But there’s boilerplate at the call site:logDebug(() -> "Normalizing " + person.toString());

Page 33: Java 8 and beyond, a scala story

Scala Traitstrait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 34: Java 8 and beyond, a scala story

Scala Traits• Allow fields

trait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 35: Java 8 and beyond, a scala story

Scala Traits• Allow fields• Participate

in lifecycle

trait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 36: Java 8 and beyond, a scala story

Scala Traits• Allow fields• Participate

in lifecycle• Support

visibility

trait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 37: Java 8 and beyond, a scala story

Scala Traits• Allow fields• Participate

in lifecycle• Support

visibility• Multiple

inheritance!

trait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 38: Java 8 and beyond, a scala story

Scala Traits• Allow fields• Participate

in lifecycle• Support

visibility• Multiple

inheritance!• By Name

eval

trait Logging { private val logger = LoggerFactory.getLogger(getClass)

protected def logWarn(msg: => String) = if (logger.isWarnEnabled) logger.warn(msg)

protected def logDebug(msg: => String) = if (logger.isDebugEnabled) logger.debug(msg)}

Page 39: Java 8 and beyond, a scala story

#2: TYPE INFERENCE

*https://visualizingreading.wikispaces.com/file/view/Detective2.gif/214220534/358x190/Detective2.gif

Page 40: Java 8 and beyond, a scala story

Type Inference

Page 41: Java 8 and beyond, a scala story

Type Inference

• …the analysis of a program to infer the types of some or all expressions, usually at compile time…

Page 42: Java 8 and beyond, a scala story

Type Inference

• …the analysis of a program to infer the types of some or all expressions, usually at compile time…

• A balance between Compile Time Safety and Verbosity

Page 43: Java 8 and beyond, a scala story

Java’s Type Inference

Page 44: Java 8 and beyond, a scala story

Java’s Type Inference• Generics class ClassWithGenerics {

<T> void generic(T param) { println(someParameter); }}...generic(“some param”)generic(5)

Page 45: Java 8 and beyond, a scala story

Java’s Type Inference• Generics

• Project Coin

class ClassWithGenerics { <T> void generic(T param) { println(someParameter); }}...generic(“some param”)generic(5)

Map<String, Int> keyCounter = new HashMap<>();

Page 46: Java 8 and beyond, a scala story

Scala’s Type Inference

Page 47: Java 8 and beyond, a scala story

Scala’s Type Inference• Generics

Page 48: Java 8 and beyond, a scala story

Scala’s Type Inference• Generics

• Local variables

Page 49: Java 8 and beyond, a scala story

Scala’s Type Inference• Generics

• Local variables

• Method return values

Page 50: Java 8 and beyond, a scala story

LET’S DIVE INTO SOME CODE

Page 51: Java 8 and beyond, a scala story

#3: PATTERN MATCHING

Page 52: Java 8 and beyond, a scala story

Java’s Switch Statement

Page 53: Java 8 and beyond, a scala story

Java’s Switch Statement• Switch statement is incredibly limited– Only supports primitives (and strings)– No arbitrary expressions (e.g. guards)– No result values

Page 54: Java 8 and beyond, a scala story

Java’s Switch Statement• Switch statement is incredibly limited– Only supports primitives (and strings)– No arbitrary expressions (e.g. guards)– No result values

• Workarounds are ugly– Nested control structures– Encoding enums instead of using types

Page 55: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:

Page 56: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:– Allows arbitrary

types

Page 57: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:– Allows arbitrary

types– Supports guards

Page 58: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:– Allows arbitrary

types– Supports guards– Checks for

exhaustiveness

Page 59: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:– Allows arbitrary

types– Supports guards– Checks for

exhaustiveness– User-extensible

Page 60: Java 8 and beyond, a scala story

Pattern Matching• Pattern matching in

Scala:– Allows arbitrary

types– Supports guards– Checks for

exhaustiveness– User-extensible– Ubiquitous

Page 61: Java 8 and beyond, a scala story

LET’S DIVE INTO SOME CODE

Page 62: Java 8 and beyond, a scala story

#4: IMPLICITS

Page 63: Java 8 and beyond, a scala story

Passing Class info (generics)

Page 64: Java 8 and beyond, a scala story

Passing Class info (generics)

• Java’s idiom is passing Class<T> clazz around

Page 65: Java 8 and beyond, a scala story

Passing Class info (generics)

• Java’s idiom is passing Class<T> clazz around

• Scala supports implicit parameters– These are filled in by the compiler–Well-defined rules for implicit search

Page 66: Java 8 and beyond, a scala story

Enhancing third party code

Page 67: Java 8 and beyond, a scala story

Enhancing third party code

• Java’s idiom is verbose wrapper methods

Page 68: Java 8 and beyond, a scala story

Enhancing third party code

• Java’s idiom is verbose wrapper methods

• Scala supports implicit methods– Verified at compile time

Page 69: Java 8 and beyond, a scala story

LET’S DIVE INTO SOME CODE

Page 70: Java 8 and beyond, a scala story

Scala’s Relevance

Page 71: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8

Page 72: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8 ✔

Page 73: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8

• Towards Java 9

Page 74: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8

• Towards Java 9

Page 75: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8

• Towards Java 9

• Java 10

Page 76: Java 8 and beyond, a scala story

Scala’s Relevance• Post Java 8

• Towards Java 9

• Java 10

✔?

Page 77: Java 8 and beyond, a scala story

QUESTIONS?

??

??

?

?

??

??

Page 78: Java 8 and beyond, a scala story

WE’RE DONE HERE!Thank you for listening

@ittaizhttp://il.linkedin.com/in/ittaizSample Code:https://github.com/ittaiz/scala-and-java8