SlideShare a Scribd company logo
1 of 106
Java, with a
Clojure mindset
@DanLebrero
www.akvo.org
((((((
((((((()))))))
))))))
Clojure
•Functional
•Hosted
•Dynamic
•Strongly typed
•Lisp
Give 10$ free cash
if client makes 1000 bets
in less than 1 week
Functional (vs OO)
Pure Functions
“Programmers are constantly in maintenance mode.”
― The Pragmatic Programmer
Side Effects
Side effects are the
enemy
Side Effects
State IO
EffectsCo-effects
State
ClientBonus12
23
54
…
Client
Bonus
DepositList
Deposit
Deposit
BetList Bet
Bet
Atom
=~ j.u.c.a.AtomicReference
Atom
Thread-1
Thread-2 fn2( ) =
fn1( ) =
====fn2( ) =
==?
==? ==?
Atom
Thread-1
Thread-2 X
Atom
Thread-1
Thread-2
Thread-3
12
23
54
…
ClientBonusClientBonus
BetList
Bet
12
23
54
…
Client
Bonus
DepositList
Deposit
Deposit
BetList Bet
Bet
“Is this thread safe?”
― Every Java developer, every day.
1. State is consistent
2. Function must be pure
3. Only safe within the pure function
public class ClientBonus {
private final Client client;
private final Bonus bonus;
private final DepositList deposits;
…
ClientBonus12
23
54
…
Client
Bonus
DepositList
Deposit
Deposit
BetList Bet
Bet
public interface ConcurrentMap<…> extends Map<…> {
V compute(K key, BiFunction<…> remappingFunction)
V computeIfAbsent(K key, Function<…> mappingFunction)
V computeIfPresent(K key, BiFunction<…> remappingFunction)
…
}
public class TheStateHolder {
private final Map<Long, ClientBonus> state = new ConcurrentHashMap<>();
public ClientBonus nextState(Long client, Bet bet) {
return state.computeIfPresent(
client,
(k, currentState) -> currentState.nextState(bet));
}
public class ClientBonus {
private final Client client;
private final Bonus bonus;
private final DepositList deposits;
public ClientBonus nextState(Bet bet) {
...
}
…
Effects
xxxxService
INotificationSender
NotificationSenderImpl
TheStateHolder
public class ClientBonus {
private final Client client;
private final Bonus bonus;
private final DepositList deposits;
public ClientBonus nextState(Bet bet) {
...
}
…
public class ClientBonus {
private final Client client;
private final Bonus bonus;
private final DepositList deposits;
public Pair<ClientBonus,Effects> next(Bet bet) {
...
}
…
NotifyClientEffect
IgnoreError
NotifyClientEffect
IgnoreError
NotifyClientEffect
StopTheJVM
NotifyClientEffect
Effect1 Effect2 Effect3SequentialEffects
Effect1
Effect2
Effect3
IndependentEffects
StopTracking Pay NotifyClient
public interface Effect {
void run(AllDependencies dependencies);
}
Pair<ClientBonus, Effects> pair = theStateHolder.nextState(bet);
pair.effects.run(dependencies);
Pair<ClientBonus, Effects> pair = theStateHolder.nextState(bet);
pair.effects.run(dependencies);
“Is this thread safe?”
Thread-1
Thread-2
Pair<> pair = theStateHolder.nextState(bet);
Pair<> pair = theStateHolder.nextState(bet);
pair.effects.run(dependencies);
pair.effects.run(dependencies);
Pair<> pair = theStateHolder.nextState(bet);
Pair<> pair = theStateHolder.nextState(bet);
pair.effects.run(dependencies);
pair.effects.run(dependencies);
Thread-1
Thread-1
Thread-2
Thread-2
Agents (=~~~ Actors)
Can I pay?Can I pay?
ACID
Can I pay?
NoYes No
AtMostOnce
StopTracking Pay NotifyClient
Co-Effects
Event Sourcing
Functional Programming
Event Sourcing
Functional Programming
public class KafkaConsumer {
private AllDependencies allDependencies;
private TheStateHolder theStateHolder;
public void run() {
while (!stop) {
Bet bet = readNext();
Effects effects = theStateHolder.event(bet);
effects.run(allDependencies);
}
}
…
}
public class KafkaConsumer {
private AllDependencies allDependencies;
private TheStateHolder theStateHolder;
public void run() {
while (!stop) {
Bet bet = readNext();
Effects effects = theStateHolder.event(bet);
effects.run(allDependencies);
}
}
…
}
public class KafkaConsumer {
private AllDependencies allDependencies;
private TheStateHolder theStateHolder;
public void run() {
while (!stop) {
Bet bet = readNext();
Effects effects = theStateHolder.event(bet);
effects.run(allDependencies);
}
}
…
}
public class KafkaConsumer {
private AllDependencies allDependencies;
private TheStateHolder theStateHolder;
public void run() {
while (!stop) {
Bet bet = readNext();
Effects effects = theStateHolder.event(bet);
effects.run(allDependencies);
}
}
…
}
public class KafkaConsumer {
private AllDependencies allDependencies;
private TheStateHolder theStateHolder;
public void run() {
while (!stop) {
Bet bet = readNext();
Effects effects = theStateHolder.event(bet);
effects.run(allDependencies);
}
}
…
}
•No getters
•No locks or synch blocks
•No try/catch
•No logging
•No mocks
•No useless interfaces
Imperative
Shell
https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell
Function
al Core
INotificationSender
NotificationSenderImpl
ClientBonus
Dynamic (vs Static) typing
clientBonus = Map.of(
"client", Map.of("id", "123233"),
"deposits",
List.of(
Map.of("amount", 3,
"type", "CASH"),
Map.of("amount", 234,
"type", "CARD")));
((List) clientBonus.get("deposits"))
.stream()
.collect(
Collectors.summarizingInt(
m -> (int) ((Map) m).get("amount")));
public class Bet {
private String id;
private int amount;
private long timestamp;
}
“It is better to have 100 functions operate
on one data structure than 10 functions on
10 data structures.”
― Alan Perlis
{:type :bet
:id "client1"
:amount 23
:timestamp 123312321323}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
{:type :bet
:id "client1"
:amount 23
:timestamp 123312321323}
{:request-method :get
:uri “/foobaz"
:query-params {"somekey" “somevalue"}
:headers {"accept-encoding" "gzip, deflate"
"connection" "close"}
:body nil
:scheme :http
:content-length 0
:server-port 8080
:server-name “localhost"}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
{:status 200
:headers {"Content-Type" "text/html"}
:body "Hello World"}}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
{:select [:id :client :amount]
:from [:transactions]
:where [:= :client "a"]}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
[{:id 1 :client 32 :amount 3}
{:id 2 :client 87 :amount 7}
{:id 3 :client 32 :amount 4}
{:id 4 :client 40 :amount 6}]
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
[:html
[:body
[:p "Count: 4"]
[:p "Total: 20"]]]
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
{:web-server {:listen 8080}
:db-config {:host "xxxx"
:user "xxxx"
:password "xxxx"}
:http-defaults {:connection-timeout 10000
:request-timeout 10000
:max-connections 2000}
:user-service {:url “http://user-service”
:connection-timeout 1000}}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
{:id :string
:name :string
:deposits [{:id :string
:amount :int
:timestamp :long}]}
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
•Business logic
•Infrastructure code
•Configuration
•Reflection/Metadata
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
Dynamic (vs Static)
development
REPL
https://danlebrero.com/repl
Lisp (vs Fortan)
.filter(removeCsvHeaders(firstHeader))
.map(splitCsvString())
.map(convertCsvToMap(csvHeaders))
.map(convertToJson(eventCreator))
(filter not-header?)
(map parse-csv-line)
(map (partial zipmap headers))
(map ->event)
1
2 3 4
5 6
7
8
9 10
11
12
13 14 15 16
1 2
3 4
87
65
9 10
-
40%!!
List.of(
new Symbol("defn"),
new Symbol("plus-one"),
List.of(
new Symbol("a"),
new Symbol("b")),
Map.of(
new Keyword("time"), List.of(new Symbol("System/currentTimeMillis")),
new Keyword("result"), List.of(
new Symbol("+"),
new Symbol("a"),
new Symbol("b"),
new Long(1))));
List.of(
new Symbol("defn"),
new Symbol("plus-one"),
List.of(
new Symbol("a"),
new Symbol("b")),
Map.of(
new Keyword("time"), List.of(new Symbol("System/currentTimeMillis")),
new Keyword("result"), List.of(
new Symbol("+"),
new Symbol("a"),
new Symbol("b"),
new Long(1))));
apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave
interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all
partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take-
nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge
merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
Summary
Imperative
Shell
Function
al Core
DYNAMIC STATIC
TYPES
DYNAMIC
STATIC
DEVELOPMENT
“A language that doesn’t affect the way you
think about programming, is not worth knowing.”
― Alan Perlis
@DanLebrero
dlebrero@gmail.com
danlebrero.com
@Akvo
https://akvo.org/
Come to ClojureCooomeeeee…Clojure is your friendClojure is happinessClojure is beauty

More Related Content

What's hot

Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Alexey Fyodorov
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency GotchasAlex Miller
 
Dynamo: Not Just For Datastores
Dynamo: Not Just For DatastoresDynamo: Not Just For Datastores
Dynamo: Not Just For DatastoresSusan Potter
 
От Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей РодионовОт Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей РодионовYandex
 
Python Asíncrono - Async Python
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async PythonJavier Abadía
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streamsmattpodwysocki
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerability
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerabilityCsw2016 gong pwn_a_nexus_device_with_a_single_vulnerability
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerabilityCanSecWest
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныНовый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныTimur Safin
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done rightPlatonov Sergey
 
Guaranteeing Memory Safety in Rust
Guaranteeing Memory Safety in RustGuaranteeing Memory Safety in Rust
Guaranteeing Memory Safety in Rustnikomatsakis
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency GotchasAlex Miller
 
Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22nikomatsakis
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCanSecWest
 

What's hot (20)

02 - Basics of Qt
02 - Basics of Qt02 - Basics of Qt
02 - Basics of Qt
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Dynamo: Not Just For Datastores
Dynamo: Not Just For DatastoresDynamo: Not Just For Datastores
Dynamo: Not Just For Datastores
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
От Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей РодионовОт Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей Родионов
 
Python Asíncrono - Async Python
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
Circuit breaker
Circuit breakerCircuit breaker
Circuit breaker
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerability
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerabilityCsw2016 gong pwn_a_nexus_device_with_a_single_vulnerability
Csw2016 gong pwn_a_nexus_device_with_a_single_vulnerability
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныНовый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоны
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done right
 
Guaranteeing Memory Safety in Rust
Guaranteeing Memory Safety in RustGuaranteeing Memory Safety in Rust
Guaranteeing Memory Safety in Rust
 
Qt Network Explained (Portuguese)
Qt Network Explained (Portuguese)Qt Network Explained (Portuguese)
Qt Network Explained (Portuguese)
 
System Calls
System CallsSystem Calls
System Calls
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22Rust tutorial from Boston Meetup 2015-07-22
Rust tutorial from Boston Meetup 2015-07-22
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemes
 

Similar to Java with a Clojure mindset

ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015Michiel Borkent
 
Exactly once with spark streaming
Exactly once with spark streamingExactly once with spark streaming
Exactly once with spark streamingQuentin Ambard
 
Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Mathias Herberts
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)Jacek Laskowski
 
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...confluent
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Data Con LA
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrencyAlex Navis
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftFlorent Pillet
 
Communicating State Machines
Communicating State MachinesCommunicating State Machines
Communicating State Machinessrirammalhar
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 
Streams Don't Fail Me Now - Robustness Features in Kafka Streams
Streams Don't Fail Me Now - Robustness Features in Kafka StreamsStreams Don't Fail Me Now - Robustness Features in Kafka Streams
Streams Don't Fail Me Now - Robustness Features in Kafka StreamsHostedbyConfluent
 
KDD 2016 Streaming Analytics Tutorial
KDD 2016 Streaming Analytics TutorialKDD 2016 Streaming Analytics Tutorial
KDD 2016 Streaming Analytics TutorialNeera Agarwal
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortStefan Marr
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptJohn Stevenson
 
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...Databricks
 
Realtime Statistics based on Apache Storm and RocketMQ
Realtime Statistics based on Apache Storm and RocketMQRealtime Statistics based on Apache Storm and RocketMQ
Realtime Statistics based on Apache Storm and RocketMQXin Wang
 
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...Databricks
 

Similar to Java with a Clojure mindset (20)

ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Exactly once with spark streaming
Exactly once with spark streamingExactly once with spark streaming
Exactly once with spark streaming
 
Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...
Data-Oriented Programming with Clojure and Jackdaw (Charles Reese, Funding Ci...
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Communicating State Machines
Communicating State MachinesCommunicating State Machines
Communicating State Machines
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 
Streams Don't Fail Me Now - Robustness Features in Kafka Streams
Streams Don't Fail Me Now - Robustness Features in Kafka StreamsStreams Don't Fail Me Now - Robustness Features in Kafka Streams
Streams Don't Fail Me Now - Robustness Features in Kafka Streams
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
KDD 2016 Streaming Analytics Tutorial
KDD 2016 Streaming Analytics TutorialKDD 2016 Streaming Analytics Tutorial
KDD 2016 Streaming Analytics Tutorial
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
The Reactive Landscape
The Reactive LandscapeThe Reactive Landscape
The Reactive Landscape
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
 
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...
Analyzing the Performance Effects of Meltdown + Spectre on Apache Spark Workl...
 
Realtime Statistics based on Apache Storm and RocketMQ
Realtime Statistics based on Apache Storm and RocketMQRealtime Statistics based on Apache Storm and RocketMQ
Realtime Statistics based on Apache Storm and RocketMQ
 
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...
Building a Versatile Analytics Pipeline on Top of Apache Spark with Mikhail C...
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 

Recently uploaded (20)

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 

Java with a Clojure mindset

  • 1. Java, with a Clojure mindset @DanLebrero www.akvo.org
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 11.
  • 12.
  • 13. Give 10$ free cash if client makes 1000 bets in less than 1 week
  • 16.
  • 17. “Programmers are constantly in maintenance mode.” ― The Pragmatic Programmer
  • 19.
  • 20. Side effects are the enemy
  • 22. State
  • 25. Atom Thread-1 Thread-2 fn2( ) = fn1( ) = ====fn2( ) = ==? ==? ==?
  • 29. “Is this thread safe?” ― Every Java developer, every day.
  • 30. 1. State is consistent 2. Function must be pure 3. Only safe within the pure function
  • 31. public class ClientBonus { private final Client client; private final Bonus bonus; private final DepositList deposits; …
  • 33. public interface ConcurrentMap<…> extends Map<…> { V compute(K key, BiFunction<…> remappingFunction) V computeIfAbsent(K key, Function<…> mappingFunction) V computeIfPresent(K key, BiFunction<…> remappingFunction) … }
  • 34. public class TheStateHolder { private final Map<Long, ClientBonus> state = new ConcurrentHashMap<>(); public ClientBonus nextState(Long client, Bet bet) { return state.computeIfPresent( client, (k, currentState) -> currentState.nextState(bet)); }
  • 35. public class ClientBonus { private final Client client; private final Bonus bonus; private final DepositList deposits; public ClientBonus nextState(Bet bet) { ... } …
  • 38. public class ClientBonus { private final Client client; private final Bonus bonus; private final DepositList deposits; public ClientBonus nextState(Bet bet) { ... } …
  • 39. public class ClientBonus { private final Client client; private final Bonus bonus; private final DepositList deposits; public Pair<ClientBonus,Effects> next(Bet bet) { ... } …
  • 46. public interface Effect { void run(AllDependencies dependencies); }
  • 47. Pair<ClientBonus, Effects> pair = theStateHolder.nextState(bet); pair.effects.run(dependencies);
  • 48. Pair<ClientBonus, Effects> pair = theStateHolder.nextState(bet); pair.effects.run(dependencies); “Is this thread safe?”
  • 49. Thread-1 Thread-2 Pair<> pair = theStateHolder.nextState(bet); Pair<> pair = theStateHolder.nextState(bet); pair.effects.run(dependencies); pair.effects.run(dependencies);
  • 50. Pair<> pair = theStateHolder.nextState(bet); Pair<> pair = theStateHolder.nextState(bet); pair.effects.run(dependencies); pair.effects.run(dependencies); Thread-1 Thread-1 Thread-2 Thread-2
  • 52.
  • 53. Can I pay?Can I pay? ACID Can I pay?
  • 57.
  • 60. public class KafkaConsumer { private AllDependencies allDependencies; private TheStateHolder theStateHolder; public void run() { while (!stop) { Bet bet = readNext(); Effects effects = theStateHolder.event(bet); effects.run(allDependencies); } } … }
  • 61. public class KafkaConsumer { private AllDependencies allDependencies; private TheStateHolder theStateHolder; public void run() { while (!stop) { Bet bet = readNext(); Effects effects = theStateHolder.event(bet); effects.run(allDependencies); } } … }
  • 62. public class KafkaConsumer { private AllDependencies allDependencies; private TheStateHolder theStateHolder; public void run() { while (!stop) { Bet bet = readNext(); Effects effects = theStateHolder.event(bet); effects.run(allDependencies); } } … }
  • 63. public class KafkaConsumer { private AllDependencies allDependencies; private TheStateHolder theStateHolder; public void run() { while (!stop) { Bet bet = readNext(); Effects effects = theStateHolder.event(bet); effects.run(allDependencies); } } … }
  • 64. public class KafkaConsumer { private AllDependencies allDependencies; private TheStateHolder theStateHolder; public void run() { while (!stop) { Bet bet = readNext(); Effects effects = theStateHolder.event(bet); effects.run(allDependencies); } } … }
  • 65. •No getters •No locks or synch blocks •No try/catch •No logging •No mocks •No useless interfaces
  • 69. clientBonus = Map.of( "client", Map.of("id", "123233"), "deposits", List.of( Map.of("amount", 3, "type", "CASH"), Map.of("amount", 234, "type", "CARD"))); ((List) clientBonus.get("deposits")) .stream() .collect( Collectors.summarizingInt( m -> (int) ((Map) m).get("amount")));
  • 70.
  • 71. public class Bet { private String id; private int amount; private long timestamp; }
  • 72. “It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.” ― Alan Perlis
  • 73. {:type :bet :id "client1" :amount 23 :timestamp 123312321323}
  • 74. apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index {:type :bet :id "client1" :amount 23 :timestamp 123312321323}
  • 75. {:request-method :get :uri “/foobaz" :query-params {"somekey" “somevalue"} :headers {"accept-encoding" "gzip, deflate" "connection" "close"} :body nil :scheme :http :content-length 0 :server-port 8080 :server-name “localhost"} apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 76. {:status 200 :headers {"Content-Type" "text/html"} :body "Hello World"}} apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 77. {:select [:id :client :amount] :from [:transactions] :where [:= :client "a"]} apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 78. [{:id 1 :client 32 :amount 3} {:id 2 :client 87 :amount 7} {:id 3 :client 32 :amount 4} {:id 4 :client 40 :amount 6}] apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 79. [:html [:body [:p "Count: 4"] [:p "Total: 20"]]] apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 80. {:web-server {:listen 8080} :db-config {:host "xxxx" :user "xxxx" :password "xxxx"} :http-defaults {:connection-timeout 10000 :request-timeout 10000 :max-connections 2000} :user-service {:url “http://user-service” :connection-timeout 1000}} apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 81. {:id :string :name :string :deposits [{:id :string :amount :int :timestamp :long}]} apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 82. •Business logic •Infrastructure code •Configuration •Reflection/Metadata apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 84. REPL
  • 87.
  • 88.
  • 89.
  • 90.
  • 92.
  • 93. List.of( new Symbol("defn"), new Symbol("plus-one"), List.of( new Symbol("a"), new Symbol("b")), Map.of( new Keyword("time"), List.of(new Symbol("System/currentTimeMillis")), new Keyword("result"), List.of( new Symbol("+"), new Symbol("a"), new Symbol("b"), new Long(1))));
  • 94. List.of( new Symbol("defn"), new Symbol("plus-one"), List.of( new Symbol("a"), new Symbol("b")), Map.of( new Keyword("time"), List.of(new Symbol("System/currentTimeMillis")), new Keyword("result"), List.of( new Symbol("+"), new Symbol("a"), new Symbol("b"), new Long(1)))); apply butlast concat cons count cycle diff distinct distinct? drop drop-last drop-while empty empty? every? ffirst filter first flatten fnext for frequencies group-by interleave interpose into into-array keep keep-indexed last lazy-cat map map-indexed mapcat next nfirst nnext not-any? not-empty not-every? nth nthnext partition partition-all partition-by pmap postwalk prewalk rand-nth reduce reductions remove replace rest reverse second seq? seque set shuffle some sort sort-by split-at split-with take take- nth take-while to-array-2d vec walk when-first assoc pop subvec replace conj rseq update-in update get get-in contains? find keys vals assoc assoc-in dissoc merge merge-with select-keys update-in update rename-keys map-invert reduce-kv dissoc-in disj join select project union difference intersection index
  • 99.
  • 100. “A language that doesn’t affect the way you think about programming, is not worth knowing.” ― Alan Perlis
  • 101.
  • 102.
  • 103.
  • 105.
  • 106. Come to ClojureCooomeeeee…Clojure is your friendClojure is happinessClojure is beauty