Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala for the Rest of Us

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Paul Cleary Paul Cleary
November 16, 2017

Scala for the Rest of Us

Presented at Scale By The Bay 2017...

Scala can be a difficult language to get into, especially for people coming from a OO Java background. Thinking functionally doesn't come naturally to people who haven't worked in it, and a lot of the concepts and patterns are foreign and often heavily abstract. Just getting started can seem like an overwhelming effort. This talk discusses the barrier to entry in moving from OO Java to Scala and what we can do to lower that barrier. I will review the Scala Pet Store and its motivation as a means to help those new to Scala understand what a complete application looks like.

Avatar for Paul Cleary

Paul Cleary

November 16, 2017
Tweet

Other Decks in Programming

Transcript

  1. Who are “The Rest Of Us” • We have spent

    years (decades) building systems using OO principles • We have little education or practice in functional programming
  2. Who are “The Rest Of Us” We build systems using

    a well known set of tools, patterns, techniques • Objects • Interfaces • SOLID • GoF • PoEAA • DDD • Simple Design • IoC • Mock Objects Lego dublo by Arto Alanenpaa, CC-BY-SA-4.0
  3. Why is learning FP so difficult? New building blocks that

    challenge our understanding of how to build systems • Functions • Currying • Partially Applied Functions • Pattern Matching • Case classes • Traits • Implicits • Property based testing Knex Misc by Nclm, CC-BY-SA-4.0
  4. Why is learning FP so difficult? New abstract ideas, concepts,

    terminology • Category Theory, Set Theory, Type Theory • Monads, Functors • Semigroups, Monoids • Algebras, Co-Algebras • Fix, Free, Identity • Free Theorems • Isomorphism, Homomorphism Lolwut cat by Riana, CC-BY-2.0
  5. Why is learning FP so difficult? You do not need

    to know all of those things to do functional programming! This is all we need bro *sigh* I’m never gonna finish this Never underestimate or overestimate by Nevit, CC-BY-SA-3.0
  6. Focus on what matters “Functional programming is programming with functions”

    Runar Bjarnason – Functional Programming for Beginners - https://www.youtube.com/watch?v=aAtPi23nLcw
  7. Focus on what matters “Functional programming is programming with functions”

    Runar Bjarnason – Functional Programming for Beginners - https://www.youtube.com/watch?v=aAtPi23nLcw // Functions in JAVA public class FunctionsOnly { public static String doSomething(String fromThis) { return "hi " + fromThis; } }
  8. Focus on what matters “a style of building the structure

    and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements. In functional code, the output value of a function depends only on the arguments that are passed to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time; this is in contrast to procedures depending on a local or global state, which may produce different results at different times when called with the same arguments but a different program state. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming” - https://en.wikipedia.org/wiki/Functional_programming
  9. Focus on what matters 1. Avoid being distracted by all

    of the abstract math 2. Learn basics: Scala syntax and the fundamentals 3. Start practicing / coding as soon as possible 4. Learn more complex ideas organically as you go
  10. Learn the basics Build on your understanding of functional programming

    by learning some fundamental techniques that will serve as a foundation for your journey • Recursion • Immutability • Avoid Unit • Pattern Matching • Working with Nulls • Business Errors • Exceptions • The Power of Monads
  11. Prefer Immutability // SCALA // DO THIS! val x =

    "123" // DON'T DO THIS! var y = "123" // SCALA case class Person(title: String, lastName: String, firstName: String)
  12. Prefer Immutability - Collections // JAVA public List<Person> getManagers(List<Person> everyone)

    { List<Person> managers = new ArrayList<>(); for (Person p : everyone) { if ("Manager".equals(p.getTitle())) { managers.add(p); } } return managers; } // SCALA def getManagers(everyone: List[Person]): List[Person] = { everyone.filter(p => p.title == "Manager") }
  13. Pattern Matching // JAVA public String show(Pet p) { if

    (p instanceof Cat) { return "I am a cat named " + p.getName(); } else if (p instanceof Dog) { return "I am a dog named " + p.getName(); } else if (p instanceof Lizard) { Lizard l = (Lizard)p; if "Godzilla".equals(l.getName())) { return "I am a VERY big lizard named " + p.getName(); } return "I am a normal lizard named " + p.getName(); } else { return "I don't know who I am, not a pet tho :("; } }
  14. Pattern Matching // SCALA def show(pet: Pet): String = pet

    match { case Cat(name) => s"I am a cat named $name" case Dog(name) => s"I am a dog named $name" case Lizard(name) if name == "Godzilla" => "I am a VERY big lizard!" case Lizard(name) => s"I am a lizard named $name" }
  15. // JAVA public String getFirstName(Person p) { if (p !=

    null) { return p.firstName; } else { return ""; } } Handling Nulls – Make optionality explicit // SCALA def getFirstName(p: Option[Person]): String = { p.map(present => present.firstName).getOrElse("") }
  16. // JAVA public static class AlreadyExistsError extends Throwable {} public

    Person create(Person p) throws AlreadyExistsError { Person existing = repo.get(p.getId()); if (existing != null) { throw new AlreadyExistsError(); } else { return repo.save(p); } } Business Errors – Instead of checked exceptions use Either // SCALA def create(p: Person): Either[AlreadyExists, Person] = { repo.get(p.id) match { case Some(_) => Left(AlreadyExists()) case None => Right(repo.save(p)) } }
  17. // JAVA public Person getPerson(String id) throws SQLException { …

    } public Company getCompany(String id) throws SQLException { … } public Employee getEmployee(String id) { try { Person p = peopleRepo.getPerson(id); Company c = companyRepo.getCompany(p.companyId); return new Employee(p, c); } catch(SQLException sqe) { return null; } } Exceptions – managing failure
  18. Exceptions – use an exception wrapper // SCALA def getPerson(id:

    String): Try[Person] = ??? def getCompany(id: String): Try[Company] = ??? def getEmployee(id: String): Try[Employee] = { getPerson(id).flatMap { person => getCompany(person.companyId).map { company => Employee(person, company) } } } 1. getPerson: if that fails then immediately exit and return the failure 2. getCompany: if that fails then immediately exit and return the failure 3. return the employee SHORT CIRCUITING
  19. flatMap == Monad == “Short Circuiting” // SCALA def getPerson(id:

    String): Try[Person] = ??? def getCompany(id: String): Try[Company] = ??? def getEmployee(id: String): Try[Employee] = { getPerson(id).flatMap { person => getCompany(person.companyId).map { company => Employee(person, company) } } } 1. getPerson: if that fails then immediately exit and return the failure 2. getCompany: if that fails then immediately exit and return the failure 3. return the employee MONAD
  20. flatMap == Monad == “Short Circuiting” == Super Powers! 1.

    getPerson: if that fails then immediately exit and return the failure 2. getCompany: if that fails then immediately exit and return the failure 3. return the employee // SCALA def getPerson(id: String): Try[Person] = ??? def getCompany(id: String): Try[Company] = ??? def getEmployee(id: String): Try[Employee] = { for { person <- getPerson(id) company <- getCompany(person.companyId) } yield Employee(person, company) } rageface_misc_freddie_mercury by meme.tn, CC-BY-2.0
  21. Start coding • Grow your knowledge organically by writing code,

    discovering problems, and solving them. • Find an example or Giter8 template that is familiar to you and get going - (Activator templates were great for this)
  22. I wanted to build an app using these things •

    Http4s • Circe • Doobie • Cats
  23. Create an example using a familiar design / structure DOMAIN

    DOMAIN SERVICES REPOSITORIES Bubble Wrap Bubble Wrap
  24. Create an example using a familiar design / structure DOMAIN

    DOMAIN DOMAIN SERVICES REPOSITORIES HTTP MQ JPA Ew Ick SHUT YOUR MOUTH!
  25. Pet Store Service Convert to a business error? Takeaway: Look

    into EitherT Learn as you go amirite!?
  26. Scala for the Rest of Us For OO Developers new

    to FP in Scala... - Avoid the trap of trying to “learn it all”, learn the basics - Start practicing / coding as soon as possible - Use examples to jump start your coding - Learn more complex ideas organically as you go For the Scala FP Community... - Demonstrate complex ideas using examples OO people can relate to - Familiar real world examples are an excellent way to drive adoption twitter: @pauljamescleary github: https://github.com/pauljamescleary/scala-pet-store