Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Functional Vaadin talk at OSCON 2014

1,141 views

Published on

An introduction on how to utilize functional programming techniques in Java 8 and Scala with Vaadin code.

Published in: Software
  • Be the first to comment

Functional Vaadin talk at OSCON 2014

  1. 1. Functional Vaadin Henri Muurimaa, SVP of Services
 henri@vaadin.com +358 400 474778 @henrimuurimaa 7
  2. 2. MissionMission Why do we exist Make building amazing web applications easy
  3. 3. Building blocks
  4. 4. Developer Productivity Rich UX
  5. 5. Web application layers JavaScriptWeb serverBackend Communication JS required required required required Vaadin required optionalrequired optional
  6. 6. Web application layers JavaScriptWeb serverBackend Communication JS required required required required Vaadin required optionalrequired optional 1 layer vs 3 layers Less code Less bugs Faster time-to-market
  7. 7. > 100.000 developers from > 10.000 cities > 450 add-ons in the
 marketplace Other 4 %Asia 20 % Americas 22 % Europe 54 % Open Source community Apache-licensed
  8. 8. Demo time
  9. 9. github.com/hezamu/WorkoutTracker
  10. 10. What is Functional Programming?
  11. 11. A style of programming that expresses computation as the evaluation of mathematical functions
  12. 12. Recursion Lazy evaluation Lambda expressions Type theory Monads Referential transparency Currying Entscheidungsproblem Pattern matching Tuples
  13. 13. Something practical? Side effects? State? Denied Denied
  14. 14. Okay…
  15. 15. What’s in it for me? A new way of thinking A new way of programming Write tight, robust and scalable code
  16. 16. What’s hot in Java 8
  17. 17. Improved Date API
  18. 18. New Java 8 Date API in action public int monthAge() { return (new Date().getYear() - date.getYear()) * 12 + (new Date().getMonth() - date.getMonth()); } // Java 8 version with the new Date API public int monthAge() { return (int) Period.between(date, LocalDate.now()).toTotalMonths(); }
  19. 19. Lambda expressions
  20. 20. Anonymous functions Runnable r = () -> System.out.println("hello lambda!”); Comparator<Integer> cmp1 = (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0); // Anonymous onsite functions button.addClickListener(event -> System.out.println("Button clicked!")); Comparator<Integer> cmp2 = (x, y) -> { return (x < y) ? -1 : ((x > y) ? 1 : 0); // Need return if not one liner };
  21. 21. Workout Tracker example editor.clear.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { editor.clearValues(); updateRating(); } }); // Java 8 version with a lambda editor.clear.addClickListener(event -> { editor.clearValues(); updateRating(); });
  22. 22. Method references with the :: notation ! private void eventHandler(Button.ClickEvent event) { // do something about the button click } button.addClickListener(this::eventHandler); // If the handler method is static button.addClickListener(MyClass::eventHandler);
  23. 23. Workout Tracker example !editor.activity.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { updateRating(); } }); // Java 8 version with a method reference editor.date.addValueChangeListener(this::updateRating);
  24. 24. Streams
  25. 25. Composable with higher order functions Streams != collections As lazy as possible Can be infinite
  26. 26. Input validation private boolean areInputsValid() { Component component = null; for (Iterator<Component> iter = editor.iterator(); iter.hasNext(); iter.next()) { if (fieldNotValidating(component)) return false; } return true; } // Java 8 version with anyMatch and a method reference private boolean areInputsValid() { return !StreamSupport.stream(editor.spliterator(), true) .anyMatch(this::fieldNotValidating); }
  27. 27. Higher order functions
  28. 28. A function that takes one or more functions as input
  29. 29. Returns a new stream by applying the given function to all elements of this stream. ! Map Returns a new stream consisting of the elements of this stream that match the given predicate. Filter SQL analogue: SELECT SQL analogue: WHERE
  30. 30. Workout Tracker Example ! ! ! // Java 8 version with stream operations private Stream<Workout> findByAge(int maxMonths) { return workouts.stream() .filter(w -> w.monthAge() < maxMonths) .sorted(Comparator.comparing(Workout::monthAge).reversed()); } private List<Workout> findByAge(int maxMonths) { List<Workout> result = new ArrayList<>(); for (Workout w : workouts) { if (w.monthAge() < maxMonths) { result.add(w); } } Collections.sort(result, new Comparator<Workout>() { @Override public int compare(Workout o1, Workout o2) { return o2.monthAge() - o1.monthAge(); } }); ! return result; }
  31. 31. Scratching the surface of Scala syntax class Cat(name: String) { initLitterBox() def meow(volume: Int = 5) = { println(s"$name meows " + (if (volume <= 5) "quietly" else "loudly")) volume <= 5 } } Class body is the constructor identifier: type notation Functions with def keyword Arguments can have default values Return keyword optional No semicolons needed
  32. 32. Burn the boilerplate - Workout.java ! ! ! public void setDuration(int duration) { this.duration = duration; } ! public double getAvgHR() { return avgHR; } ! public void setAvgHR(double avgHR) { this.avgHR = avgHR; } ! public double getMaxHR() { return maxHR; } ! public void setMaxHR(double maxHR) { this.maxHR = maxHR; } ! public int getCalories() { return calories; } ! public void setCalories(int calories) { this.calories = calories; } ! public String getComment() { return comment; } ! public void setComment(String comment) { this.comment = comment; } } public class Workout { private String activity; private Date date; private int duration, calories; private double avgHR, maxHR; private String comment; ! public Workout(String activity, Date date, int time, double avgHR, double maxHR, int kcal, String comment) { this.activity = activity; this.date = date; this.duration = time; this.avgHR = avgHR; this.maxHR = maxHR; this.calories = kcal; this.comment = comment; } ! public int monthAge() { return (int) Period.between(date, LocalDate.now()).toTotalMonths(); } ! public String getActivity() { return activity; } ! public void setActivity(String activity) { this.activity = activity; } ! public Date getDate() { return date; } ! public void setDate(Date date) { this.date = date; } ! public int getDuration() { return duration; }
  33. 33. Equivalent Workout.scala ! ! ! case class Workout(activity: String, date: LocalDate, duration: Int, avgHR: Double, maxHR: Double, calories: Int, comment: String) { def monthAge = Period.between(date, LocalDate.now).toTotalMonths }
  34. 34. github.com/henrikerola/scaladin
  35. 35. An example // Scaladin val layout = new VerticalLayout { margin = true ! add(Label("Hello, OSCON!"), alignment = Alignment.TopCenter) add(Button("Click me”, handleButtonClick)) } // Java 7 VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); Label label = new Label(“Hello, OSCON!”); layout.addComponent(title); layout.setComponentAlignment(label, Alignment.TOP_CENTER); ! Button button = new Button(“Click me", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { handleButtonClick(); } }); layout.addComponent(button);
  36. 36. Input validation, Java 8 & Scala // Scaladin version of the editor gives us the components as a Scala Set // which supports functional operations. private def areInputsValid = !editor.components.exists(fieldNotValidating) // Java 8 version with anyMatch and a method reference private boolean areInputsValid() { return !StreamSupport.stream(editor.spliterator(), true) .anyMatch(this::fieldNotValidating); }
  37. 37. Summary
  38. 38. SLOC comparison Java 7 Java 8 Scala UI 267 264 175 Presenter 168 128 84 POJO 82 82 8 All versions: zero lines of HTML, JavaScript, RPC code or browser specific tweaks
  39. 39. Henri Muurimaa, SVP of Services
 henri@vaadin.com +358 400 474778 @henrimuurimaa

×