2. About me
● I’m Manuel Rivero (@trikitrok).
● I’m a member of Codesai.
● I collaborate with BCN Software
Craftsmanship, Clojure
Developers BCN and
Aprendices (@deAprendices)
communities.
● My current client is
Green Power
Monitor where we
develop a SPA for
monitoring and
managing renewable
energy portfolios
using ClojureScript
and Om.
3. Thanks to:
● All the members of Clojure Developers BCN for all
the fun and evenings of sharing and learning.
● All the people in Codesai & Green Power Monitor
that gave me feedback to improve this talk.
● Francesc Guillén for introducing me to
ClojureScript, teaching me so much,
and letting me participate in his re-frame
+ React Native adventure.
4. Context
● Rewrite in ClojureScript a browser SPA written in
JavaScript that implements a visual method to
practice spelling.
● Create a mobile version, adding some improvements
and making it offline first.
● We wanted to share as much code as possible
between browser and mobile versions.
5. Stack
● ClojureScript.
● re-frame, a framework for writing SPAs in Clojurescript.
● Reagent a minimalistic interface between ClojureScript
and React.
● expo to build React Native apps that work across both
iOS and Android.
11. State Management
● At any point in time, app state results from
reducing over all events dispatched in the app
up until that time.
● The combining function for the reduce is the
set of registered event handlers.
31. Effects and Coeffects
● Effects: describe your program’s
side-effects (what it does to the world)
● Coeffects: track your program’s
side-causes (what it requires from the world)
32. Declarative Effects pattern
● Event handlers are pure functions again
● They receive coeffects and return effects
● Injecting the values coeffects track and interpreting
effects to actually perform side-effects are done by
sth else (the language run-time, a framework, etc)
44. Effect & Coeffects handlers in re-frame
● Built-in effects handlers (:db, :dispatch, :dispatch-later, etc)
● Built-in coeffects handlers (:db)
● You can create your own custom effects and
coeffects handlers and register them into re-frame.
48. Advantages over ports & adapters
● Less accidental complexity in business logic
● Remove business logic fragility to interface
changes in ports
● Still keeps pluggability (you can still use ports &
adapters in the imperative shell)
51. re-frame subscriptions
● A novel and efficient de-duplicated
signal graph which runs query
functions on the app state
● These query functions extract data from
the app state and provide it to view
functions in the right format
57. Simpler model & Dumb Views
● Avoid having to keep derived state in
the model (app state).
● Dumb down the views, that end up
being simple “data in, screen out”
functions
66. A Pit of Success
“A well-designed system makes it
easy to do the right things and
annoying (but not impossible) to do
the wrong things.” Jeff Atwood
67. A Pit of Success
Functional architecture: The pits of success, Mark Seemann
70. UI modeled as FSMs
from a great Jeb Beich’s post in Cognitect’s blog
71. Subscriptions
● Reduce accidental complexity by
avoiding derived state
● Dumb views down
● Allow separated optimization of query
code using a reactive de-duplicated
signal graph
84. Hard things are still hard
re-frame puts you in a great starting point
However, you still have to work hard to get
good naming, model your domain,
discover useful abstractions and organize
your code
85. Beware of “shape” coupling
● Avoid that your code knows too
much about the app-state
representation.
● Especially important for tests.
Use builders.
86. Beware of long event cascades
● Some business logic might be
difficult to follow.
● Common problem in all
event-based systems:
● Paliate with tooling (re-frisk)
and packaging by feature.
87. Living on the bleeding edge
● expo: early days & quickly evolving =>
ClojureScript bindings continually
catching up.
● Still worth it though: avoids maintaining
different views for iOS and Android.
● It’ll get better as it stabilizes.
89. ● Browser and mobile versions share most
of its code
● Effects, coeffects & subscriptions
○ Removes a lot of accidental complexity
○ A “pit of success”
● ClojureScript:
○ sound language
○ great interactive development flow
91. References & Links
● Effects & Coeffects
○ Coeffects: The next big programming challenge, Tomas Petricek
○ Side-effect, Wikipedia
○ What is functional programming?, Kris Jenkins
○ Avoiding Action at a Distance Is the Fast Track to Functional Programming, Ashley
Nelson-Hornstein
○ Effects as Data, Richard Felman
○ Unidirectional data flow architectures, Andre Staltz
○ Using coeffects in re-frame, Manuel Rivero
○ Using effects in re-frame, Manuel Rivero
○ Creating custom effects in re-frame, Manuel Rivero
○ An Introduction to Elm
○ Boundaries, Gary Bernhardt
92. References & Links
● UIs modeled as FSMs
○ Using State Machines to Simplify User Interface Development, Jeb Beich
○ Creating a User Interface with Re-frame and State Machines, Jeb Beich
● Pits of success
○ Functional architecture: The pits of success, Mark Seemann
○ Falling Into The Pit of Success, Jeff Atwood
○ A Good Language Conserves Programmer Energy, Eugene Wallingford
○ The deep synergy between testability and good design, Michael Feathers
● Simplifying React
○ 6 things Reacters do that Re-framers avoid, Eric Normand
○ A guide to the React Lifecycle Methods for Re-frame, Eric Normand
○ JSX vs Clojurescript: the showdown, Inge Solvoll
○ Comparing Reagent to React.js and Vue.js for dynamic tabular data, Dmitri Sotnikov
93. References & Links
● Interactivity
○ Developing ClojureScript With Figwheel, Bruce Hauman
○ Repl Driven Development, Stuart Sierra
● Other interesting links
○ Interview with Yassine Elouafi, creator of redux-saga
○ Elm architecture with React + Redux + Redux-loop, Egor Sapronov
○ Rethinking All Practices: Building Applications in Elm, Jamison Dance
○ Reduce side effects in React/Redux, Michal Zalecki
○ Managing side effects in Redux, Rico Sta. Cruz
○ Offline first
○ re-frame
○ Reagent
94. References & Links
○ React Native
○ re-natal
○ expo
○ Redux
○ reselect
○ redux-saga
○ redux-loop
○ Clojure Developers BCN Meetup
○ Aprendices Community on G+
○ Clojure Barcelona Community on G+
Note for myself: inevitable actually exists and means unavoidable... (see
the video of the talk when it comes out )
95. re-frame: how it works
discarded slide copied from
wonderful re-frame docs