Applying this functional stuff

in your Java project


Anton Keks / @antonkeks / Codeborne

Or Java developer's quest for answers

(Groovy, Scala, Clojure, Node/JS, Python, Ruby, ...)


And how to apply the learnt in Java

Which Java do you use?


1.8

1.7

1.6

1.5?

None at all?

OOP is deaddying

Object-Oriented Programming


40+ years old and still has problems

"Modeling-driven" programming

How often do your classes model real-world stuff?


(a good read)

OOP quotes


“I don't think object-oriented programming is a structuring paradigm that meets my standards of elegance.” – Edsger Dijkstra

“The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” – Joe Armstrong

Specialty of this

Extra parameter, used for function dispatch

Pattern matching - more powerful concept

Reuse of whole classes instead of smaller functions

Mutable state

Unsafe to return

No caching

No sharing

Concurrency issues

Nowadays

People use less OOP features in langs like Java

Code reuse is hard in OOP

E.g. DI & AOP try to solve that

SOA = going back to procedures ;-)

Functional programming

Much hyped currently


Most people still use OOP / Imperative

Hoping we can do better :-)

Why make programming even harder?


Program some Java - your C++ will improve

Program some X - your Java will improve

But look around!

Functional programming


Initially mostly in academics


Now even in JavaScript :-)

And most modern languages

And even Java 8

It's good for your code


immutable

stateless

side-effect free


⬆ Functions ⬆

Reasons

more work to the compiler

implicit optimizations:
parallelism, late evaluation, memoization, ...

less code -> readability, productivity

fewer bugs

Functions in Java

Utility functions ⇒ static imports (but not static state)

unmodifiableList(asList(1, 2, 3));

Function composition ⇒ delegate, composite?

⇒ reuse through composition


Java 8: java.util.function.* and Method references

Guava: Function and Predicate

p = Predicates.or(containsPattern("b"), containsPattern("3"));

Good old Decorator pattern

Hamcrest, Mockito

Stateless

Play framework sessions

Testing

Data

vs

Objects


Clojure: data is more important than representation

Represent computation, not the world

Breaking data into objects is often arbitrary

Tuple in Java: asList()
convenient, semi-immutable, ok for heterogeneous items

(a good read)

Collections / Iterables

First-class citizens

3 Lispy workhorses: map, reduce, and filter

Chaining

Lazy (delayed evaluation)

Available in Java 8 and Guava

Immutables

are everywhere in Java API since 1.0

what about your classes?

Parallelism

Concurrency

Multithreading

Synchronization is hard

Not needed if there is no shared state

Bonus: easier to test

Clojure: agents

Scala/Akka: actors

Erlang: processes

Dart: isolates


⇒ no shared data

⇒ message passing


JavaScript: no concurrency (async)

JavaScript


Dynamic, semi-functional, single threaded

Named after Java because of its popularity

JSON

data as first-class citizen

JSON = JavaScript Object Notation

Async

NodeJS

You can actually do a lot in a single thread!

java.nio

Play framework + Netty


But, code ladder

But, promises

Reactive programming

Like in a spreadsheet

Or triggers in DB

Angular, Knockout, etc

input ⇒ work ⇒ output ⇒ repeat

In Java can be emulated with Observer

JQuery

Revolutionized web development

What does it do well?

Short, simple syntax

$('#hello').val('world')

Everything is a collection

Implicit iterations

Chaining

$('a').parent().addClass('nice').end().on('click', ...)

In Java?

Selenide - UI Testing Framework


open("http://www.google.ee/");
$("[name=q]").val("Hello").pressEnter();
$("#ires").shouldBe(visible);
		

or the first-ever chaining class


			new StringBuffer().append("Hello").append("World").toString()
		

and any other Builder

Nulls

Probably, one of the mistakes of Java

inherited from C++ and others

NullPointerException

How others fare?

Objective-C: no NPEs when sending messages!

[greeter sayHelloTo:@"World" and:@"Universum"];

Groovy: ?: and ?. to avoid NPE

greeter?.sayHelloTo(world ?: "World")

Vala & Kotlin: ? to mark nullables

String? nullable = null;  String neverNull = "a";

Scala: Option

val s: Option[String] = Some("Hello"); s.getOrElse("World")

SQL is just bad

How Java devs fight nulls?

"hello".equals(greeting)

java.util.Objects @since 1.7

Objects.equals(a, b); Objects.compare(a, b);

Guava Objects/MoreObjects/Strings

firstNonNull(s, "x")
isNullOrEmpty(s)

Java 8 / Guava: Optional

Optional.of("hello").orElse("x")

@Nullable + @Nonnull

Dependency Injection

Comes to the rescue...

...when OOP gets messy


Simplifies building object graphs ⇒ loose coupling

Dependencies are resolved at run-time

Dependency Injection

...is dynamic programming

Dependency Injection

...is also functional?


Injector can do high-level optimizations

...free to decide the best way to create objects


⇒ memoization (caching), pooling, reordering and parallelizing

⇒ should be no side effects in constructors


(a good read)

Guice

Declarative code for configuration


			bind(Something.class).to(SuperSomething.class);
		

Bootstrap


Injector injector = Guice.createInjector(new MyModule());
Something s = injector.getProvider(Something.class).get();
		

Use


class SuperSomething implements Something {
  @Inject AnotherThing another;
}
		

Makes AOP look not so bad


			bindInterceptor(any(), annotatedWith(Cache.class),
			invocation -> ...);
		

AOP

Aspect-Oriented Programming


Much hyped in mid-2000s

Crazy terminology, disastrous implementations

Actually means wrapping of methods (advices)

for Caching, Logging, etc

i.e. keeping code cleaner

Dynamic

vs

Static

What I learned?

"Change + Refresh" workflow

Quick prototyping

Duck typing is convenient

DSLs


But...

Static compilation is so much better for refactoring

Unit tests with 100% coverage are essential

IDE support...

Outcomes

Dart, TypeScript: optional types

Scala et al: type inference, implicits, duck typing

Tips for Java

Play framework (1.x)

spring-loaded

Design your API as DSL

Boilerplate

Java has a lot; very verbose; violates DRY

You learn to hate it

More clean code (tm)

Java boilerplate

getters/setters

Java Beans convention...

JQuery: val() & val("x")

null checks

iterations

Fixing Java boilerplate

there shouldn't be so much, most can be hidden

don't generate code

mostly, it boils down to API

meaning, your own API can be a lot better!

smaller units of reuse - functions

Macros

#preprocessing in C

Scala/Clojure

Java: AnnotationProcessing in javac

Many frameworks appearing, eg:
Dagger, Lombok, and even Java-OO

Guava

FluentIterable

Iterables, Maps, Predicates, Functions, Ordering

New collections: Multimap, BiMap, Table, Immutable*

Promotes immutable collections

Like design patterns

Many of those bring more of

dynamic and functional

to Java et al

Simplicity

Clean code

Easy to read

Easy to write

(fewer bug possibilities)

Easy to compile

Easy to run


(a good read)

And what others can learn from Java?

Cross-platform

Unicode since 1995

JIT, performance

Backward compatibility

(both binary and source level)

Thanks!


slides:// angryziber.github.io/slides


Anton Keks / @antonkeks / codeborne.com