Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Go Pure with ClojureScript
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Marcelo Piva
July 13, 2019
Programming
2
190
Go Pure with ClojureScript
Marcelo Piva
July 13, 2019
Tweet
Share
More Decks by Marcelo Piva
See All by Marcelo Piva
Building a sustainable architecture
mpivaa
1
120
Maintaining consistency in distributed systems with an effect machine
mpivaa
1
290
Fun with Monads
mpivaa
2
200
Other Decks in Programming
See All in Programming
エンジニアの「手元の自動化」を加速するn8n 2026.02.27
symy2co
0
180
GoのDB アクセスにおける 「型安全」と「柔軟性」の両立 - Bob という選択肢
tak848
0
270
Laravel Nightwatchの裏側 - Laravel公式Observabilityツールを支える設計と実装
avosalmon
1
150
Angular-Apps smarter machen mit Gen AI: Lokal und offlinefähig - Hands-on Workshop!
christianliebel
PRO
0
130
PHP でエミュレータを自作して Ubuntu を動かそう
m3m0r7
PRO
2
130
Vuetify 3 → 4 何が変わった?差分と移行ポイント10分まとめ
koukimiura
0
180
Fundamentals of Software Engineering In the Age of AI
therealdanvega
2
290
今年もTECHSCOREブログを書き続けます!
hiraoku101
0
120
[SF Ruby Feb'26] The Silicon Heel
palkan
0
120
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
950
「接続」—パフォーマンスチューニングの最後の一手 〜点と点を結ぶ、その一瞬のために〜
kentaroutakeda
3
1.8k
飯MCP
yusukebe
0
230
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
55
8k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
170
How to train your dragon (web standard)
notwaldorf
97
6.6k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
85
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
400
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
990
Side Projects
sachag
455
43k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
460
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
220
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
150
Transcript
Go Pure with ClojureScript
Marcelo Piva Software Engineer @ Nubank @mpivaa github.com/mpivaa instagram.com/m.pivaa
None
None
?
? Why
Consistency Predictability Safety
Consistency Predictability Safety
Consistency Predictability Safety
Immutability Pure functions
Pure functions Input Output No side effects Isolated from the
world Transforms input -> output
Pure functions let eat = (food) => { let foodList
= [, , , ] if(foodList.includes(food)) { return } else { return } }
Pure functions eat() // => eat() // =>
Easy to test describe("eat", () => { it("returns when ",
() => { expect(eat()).toBe() }) })
Impure functions let eat = (food) => { let foodList
= [, , , ] if(foodList.includes(food)) { console.log() } else { console.log() } } Not testable, depends on the world
Immutability Never change a value, create a new one
Immutability Functions are black boxes, changing their input is unpredictable
Immutability Image: joy of clojure
Immutability Concurrency is easy
Consistency
Class Object Instance Inheritance Polymorphism Abstract Factory Builder Factory Method
Object Pool Prototype Singleton Adapter Bridge Composite Decorator Facade Flyweight Private Class Data Proxy Chain of responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State
None
None
Immutability ❌ First class functions ✅ Consistency ❌
First class functions ✅ let temperatures = [10, 20, 30]
let celsius2fahrenheit = (t) => t * 1.8 + 32 temperatures.map(celsius2fahrenheit) // => [ 50, 68, 86 ]
First class functions ✅ let temperatures = [10, 20, 30]
let celsius2fahrenheit = (t) => t * 1.8 + 32 temperatures.map(celsius2fahrenheit) // => [ 50, 68, 86 ]
First class functions ✅ let temperatures = [10, 20, 30]
let celsius2fahrenheit = (t) => t * 1.8 + 32 temperatures.map(celsius2fahrenheit) // => [ 50, 68, 86 ]
First class functions ✅ let temperatures = [10, 20, 30]
let celsius2fahrenheit = (t) => t * 1.8 + 32 temperatures.map(celsius2fahrenheit) // => [ 50, 68, 86 ]
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { acc.status = "blocked" return acc } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "blocked"}
Spread operator const Immutability ❌
Immutability ❌
const Immutability ❌
const? const foo = {bar: 1} foo = {bar: 2}
// => SyntaxError: Identifier 'foo' has already been declared foo.bar = 2 foo // => {bar: 2}
const? const foo = {bar: 1} foo = {bar: 2}
// => SyntaxError: Identifier 'foo' has already been declared foo.bar = 2 foo // => {bar: 2}
const? const foo = {bar: 1} foo = {bar: 2}
// => SyntaxError: Identifier 'foo' has already been declared foo.bar = 2 foo // => {bar: 2}
Spread operator Immutability ❌
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { return {...acc, status: "blocked"} } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "active"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { return {...acc, status: "blocked"} } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "active"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { return {...acc, status: "blocked"} } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "active"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { return {...acc, status: "blocked"} } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "active"}
Immutability ❌ let account = {id: "acc-1", status: "active"} let
account2blocked = (acc) => { return {...acc, status: "blocked"} } account2blocked(account) // => {id: "acc-1", status: "blocked"} account // => {id: "acc-1", status: "active"}
Immutability ❌ Performance ❌
Immutability ❓
Consistency ❌
Consistency ❌
Consistency ❌
Consistency ❌
Consistency ❌ null undefined absent
Immutability ✅ First class functions ✅ Consistency ✅
First class functions ✅ (def temperatures [10 20 30]) (defn
celsius->fahrenheit [t] (+ 32 (* t 1.8))) (map celsius->fahrenheit temperatures) ; => [50.0 68.0 86.0]
First class functions ✅ (def temperatures [10 20 30]) (defn
celsius->fahrenheit [t] (+ 32 (* t 1.8))) (map celsius->fahrenheit temperatures) ; => [50.0 68.0 86.0]
First class functions ✅ (def temperatures [10 20 30]) (defn
celsius->fahrenheit [t] (+ 32 (* t 1.8))) (map celsius->fahrenheit temperatures) ; => [50.0 68.0 86.0]
First class functions ✅ (def temperatures [10 20 30]) (defn
celsius->fahrenheit [t] (+ 32 (* t 1.8))) (map celsius->fahrenheit temperatures) ; => [50.0 68.0 86.0]
Immutability ✅ (def account {:id "acc-1" :status :active}) (defn account->blocked
[acc] (assoc acc :status :blocked) (account->blocked account) ; => {:id "acc-1" :status :blocked} account ; => {:id "acc-1" :status :active}
Immutability ✅ (def account {:id "acc-1" :status :active}) (defn account->blocked
[acc] (assoc acc :status :blocked) (account->blocked account) ; => {:id "acc-1" :status :blocked} account ; => {:id "acc-1" :status :active}
Immutability ✅ (def account {:id "acc-1" :status :active}) (defn account->blocked
[acc] (assoc acc :status :blocked) (account->blocked account) ; => {:id "acc-1" :status :blocked} account ; => {:id "acc-1" :status :active}
Immutability ✅ (def account {:id "acc-1" :status :active}) (defn account->blocked
[acc] (assoc acc :status :blocked) (account->blocked account) ; => {:id "acc-1" :status :blocked} account ; => {:id "acc-1" :status :active}
Immutability ✅ (def account {:id "acc-1" :status :active}) (defn account->blocked
[acc] (assoc acc :status :blocked) (account->blocked account) ; => {:id "acc-1" :status :blocked} account ; => {:id "acc-1" :status :active}
Structural Sharing A =
Structural Sharing A = B =
Structural Sharing
Structural Sharing A
Structural Sharing B
Consistency ✅
Consistency ✅ Only nil
None
JVM Bytecode
JVM Bytecode Node / Browser Javascript
Interop Using JS inside ClojureScript
React
is a LISP
None
LISP LISt Processing
LISP Developed in 1959
LISP Multiple dialects
JS was based on a LISP Based on Scheme, a
LISP dialect
LISP (10 20 30)
LISP No Syntax, everything is a LIST (defn celsius->fahrenheit [t]
(+ 32 (* t 1.8)))
LISP No Syntax, everything is a LIST (defn celsius->fahrenheit [t]
(+ 32 (* t 1.8)))
LISP No Syntax, everything is a LIST (defn celsius->fahrenheit [t]
(+ 32 (* t 1.8)))
LISP No Syntax, everything is a LIST (defn celsius->fahrenheit [t]
(+ 32 (* t 1.8)))
LISP Homoiconic: CODE = DATA (defn celsius->fahrenheit [t] (+ 32
(* t 1.8)))
Dynamic Code easy to manipulate
None
Macros Functions that generate code
Macros Resolved in compile time
Macros Unless macro
Macros Unless macro
Macros Unless macro
Macros Unless macro
Pipeline operator ⚠
Threading macro
Threading macro
Threading macro
Types
Types
Pattern matching ⚠
Pattern matching ⚠
None
REPL Read Eval Print Loop
None
REPL Change code on runtime
Consistency Predictability Safety
?
None
Thanks! We're hiring! @mpivaa github.com/mpivaa instagram.com/m.pivaa https://nubank.workable.com/ https://t.me/clojurebrasil https://www.braveclojure.com