SlideShare a Scribd company logo
1 of 58
Download to read offline
How to Lose FP at Work
If you're looking to lose functional programming at work, here are a
bunch of mistakes I've made on JS-heavy web teams over the
years that can help you do the same! /s
web !" rwp.im
github !" rpearce
email !" me@robertwpearce.com
tweeter !" @RobertWPearce
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
About me
𝝺 Work at Articulate (articulate.com / rise.com) doing web dev work (heaps
of accessibility work, too)
𝝺 12 years experience in the web world
𝝺 Enjoy Nix(
⚙
), Haskell(λ), Rust(
"
), Elixir( ), and even Go( ) on the side
𝝺 Was writing the Ramda Guide (ramda.guide), but life intervened, and I may
strip it for parts
𝝺 Perpetual beginner-/intermediate-level FP practitioner
𝝺 Am a dad with another on the way!
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Disclaimers/Heads up
𝝺 This backwards-style talk will be sarcastic, snarky, and cringey
𝝺 The examples are more JS-oriented, but the commentary is
mostly universal
𝝺 The examples are all my examples and personal work-related
head-canon; this should not reflect poorly on my colleagues nor
my employer
𝝺 The slides aren't shouting at you — they're shouting at me
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"Do"s and "Don't"s
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Don't
have static type checking
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
𝝺 No TypeScript
𝝺 No Flow
𝝺 No ReasonML
𝝺 No Elm
𝝺 No (insert language with static type checking that compiles to
JS)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
const processData = composeP(syncWithBackend, cleansePII, validateData)
!" * What arguments and their types are expected here?
!"
!" * If each function is written like this, how can
!" one suss out what data are flowing where?
!"
!" * How hard is this going to be to debug?
!" Use this everywhere: `(x) !# (console.log(x), x)`
So the point-free style is the problem? Not so fast…
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
async function processData(data) {
await validateData(data)
const cleansedData = cleansePII(data)
await syncWithBackend(cleansedData)
return data
}
!" or for the Promise-chainers…
const processData = data !#
validateData(data)
.then(cleansePII)
.then(syncWithBackend)
.then(() !# data)
!"
!
Are these any clearer? Y/n? ¯_(ツ)_/¯
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Don't
use well-known documentation tools
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
𝝺 No jsdoc
𝝺 …are there any other JS contenders?
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Deprive your team of this clarity and helpful auto-completion:
/**
* @typedef {Object} ReportingInfo
* @property {("light"|"dark")} userTheme - Current user's preferred theme
* @property {string} userName - Current user's name
* @property {UUID} postId - The current post's ID
!"
/**
* Validates that the reporting data (current user site prefences and post info)
* is OK, removes personally identifiable information, syncs this info with the
* backend, and gives us back the original data.
*
* @param {ReportingInfo} data - The current user's site preferences and post info
* @returns {Promise<ReportingInfo>} - The original reporting data
!"
const processData = data !# { !$ … !" }
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Don't
properly train new and existing
colleagues
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"Here, go read all these posts and
books, watch these videos, and let
me know if you have any questions!"
— Me
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Don't
bother getting the other
engineering teams on board and
rowing
!
in the same direction
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
𝝺 "If I build it, they will notice… right?"
𝝺 Idea: Lunch 'n learn about FP?
❌
𝝺 Idea: Meet with other team leaders?
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
live by "Point-free or die"
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"Think it's point-less?
Go watch Point-Free or Die:
Tacit Programming in
Haskell and
Beyond by Amar Shah"
— Me
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
import { !", any, lt } from 'ramda'
const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it
anyLt0([1, 2, 3]) !# true — ugh…
!# vs. the probably pretty simple…
const anyLt0 = numbers !$ numbers.some(n !$ n < 0)
anyLt0([0, 1, 2, 3]) !# false
anyLt0([0, 1, 2, -1, 3]) !# true — looks good
!#
!#
!#
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
import { !", any, lt } from 'ramda'
const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it
anyLt0([1, 2, 3]) !# true — ugh…
!# vs. the probably pretty simple…
const anyLt0 = numbers !$ numbers.some(n !$ n < 0)
anyLt0([0, 1, 2, 3]) !# false
anyLt0([0, 1, 2, -1, 3]) !# true — looks good
!#
!
should we resist eta-converting this?!
!#
!#
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
import { !", any, lt } from 'ramda'
const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it
anyLt0([1, 2, 3]) !# true — ugh…
!# vs. the probably pretty simple…
const anyLt0 = numbers !$ numbers.some(n !$ n < 0)
anyLt0([0, 1, 2, 3]) !# false
anyLt0([0, 1, 2, -1, 3]) !# true — looks good
!#
!
should we resist eta-converting this?!
!# …
!#
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
import { !", any, lt } from 'ramda'
const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it
anyLt0([1, 2, 3]) !# true — ugh…
!# vs. the probably pretty simple…
const anyLt0 = numbers !$ numbers.some(n !$ n < 0)
anyLt0([0, 1, 2, 3]) !# false
anyLt0([0, 1, 2, -1, 3]) !# true — looks good
!#
!
should we resist eta-converting this?!
!# …
!# NOT ON MY WATCH
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
const any = fn !" array !" array.some(fn)
const isLtN = x !" n !" x < n
const isLt0 = isLtN(0)
const anyLt0 = any(isLt0)
anyLt0([1, 2, 3]) !# true — ugh; the bug is back
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Real, but altered, example:
const finishItems = compose(
flip(merge)({ isDone: true, amtComplete: 100 }),
over(
lensProp('indexedObjects'),
mapVals(
compose(
over(lensProp('indexedObjects'), mapVals(assoc('isDone', true))),
assoc('isDone', true)
)
)
)
)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
prefer the wrong abstraction over
the right duplication
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"Prefer duplication over the wrong
abstraction"
— Sandi Metz’ RailsConf 2014 talk, All the Little Things
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Instead…
1. Dilute core business logic to broad generalizations
2. Fail to understand category theory enough for this to be useful
3. Be the only one who knows how these abstractions work
4. Previously thorough PR-reviews now look like " "
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Don't
refactor old patterns that clearly
don't work for the team
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
force functional patterns into a
language that wasn't built for
them
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
𝝺 Recursive functions
𝝺Handle with trampolines if you really want them
𝝺 Cryptic stack traces thanks to currying and composing functions
𝝺Debugging functional by Brian Lonsdorf
𝝺Partially-applied (or curried) functions could
obfuscate the JavaScript stack trace by Thai
Pangsakulyanont
𝝺 No GHC-style fusing of .map(…).map(…).map(…)
𝝺 BYO algebraic data type libraries (they're well done, though)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
opaquely compose and sequence the
entirety of your API endpoints and
make them hard to debug
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
On the surface, this isn't
so difficult to read…
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
!" handler for POST /posts
import { createPost } from 'app/db/posts'
import { authenticateUser, authorizeUser } from 'app/lib/auth'
import { trackEvent } from 'app/lib/tracking'
const validateRequestSchema = payload !# { !$ … !% }
export const handleCreatePost = curry(metadata !#
pipeP(
authenticateUser(metadata),
authorizeUser(metadata),
validateRequestSchema,
createPost(metadata),
tapP(trackEvent('post:create', metadata)),
pick([ 'id', 'authorId', 'title' ])
)
)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Did you catch or wonder about
these?
𝝺 handleCreatePost expects 2 arguments?
𝝺 authenticateUser ignores the 2nd curried parameter sent to it?
How would you?
𝝺 Does trackEvent receive the payload passed through or the
result of the createPost() fn?
Let's try something else…
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
export async function handleCreatePost(metadata, payload) {
await authenticateUser(metadata)
await authorizeUser(metadata, payload)
await validateRequestSchema(payload)
const post = await createPost(metadata, payload)
await trackEvent('post:create', metadata, post)
return {
id: post.id,
authorId: post.authorId,
title: post.title,
}
}
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
✅
Not forcing different
arity functions into a
pipeline pattern
!
But if you want to make things
trickier for people, go with the
first approach
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
recreate imperative, procedural
programming while calling it
"declarative"
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
const setBookReadPercentByType = (contentType, statusObject) !"
assoc(
'readPercent',
pipe(
prop('subItems'),
values,
filter(propEq(contentType, 'chapter')),
length,
flip(divide)(compose(length, keys, prop('subItems'))(statusObject)),
multiply(100),
Math.round
)(statusObject),
statusObject
)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
have 8+-ish different patterns for
function composition
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
!
These 4, plus Promisified versions of each, plus combinations of them all used
at once; doesn't include ramda's even more abstract composeWith and pipeWith
!" compose (plus composeP for Promises)
const getHighScorers =
compose(
mapProp('name'),
takeN(3),
descBy('score')
)
!" pipe (plus pipeP for Promises)
const getHighScorers =
pipe(
descBy('score'),
takeN(3),
mapProp('name')
)
!" composeWithValue
const getHighScorers = players !#
composeWithValue(
mapProp('name'),
takeN(3),
descBy('score'),
players
)
!" pipeWithValue (plus pipePWithValue for Promises)
const getHighScorers = players !#
pipeWithValue(
players,
descBy('score'),
takeN(3),
mapProp('name')
)
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
make yourself one of the few who
can debug algebraic data types
during midnight incidents
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Ensure your team is surprised by
all of the following words when
debugging or altering your code in
the pursuit of their own tasks:
𝝺 Task, Maybe, Either, Result, Pair, State
𝝺 bimap
𝝺 chain
𝝺 bichain
𝝺 option
𝝺 coalesce
𝝺 fork
𝝺 sequence
𝝺 ap
𝝺 map — and I don't mean Array.prototype.map, nor
a new Map(), nor a key/value object
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
suggest, on PRs, that colleagues
completely refactor what they've
done to fit your functional style
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"What you have here works great, but
what could this look like if we flipped all
the function arguments around,
removed all these intermediate
variables and if/else if/elses, and
mapped these operations over an
Either?"
— Me
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
"I noticed you're explicitly constructing
these objects in their functions. If
you were to use <UTILITY-FUNCTION>,
you could declare the shape of your
outputted object and use functions as
the values to look up or compute each
value given some data."
— Me
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Ok, last ones!
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
sow imposter syndrome in others
and exclude them by sharing non-
beginner FP articles
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
Do keep writing code using FP
tools even when nobody else on the
team is
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
achieve peak perceived passive-
aggression by getting tired and
commenting PRs with emojis
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Do
have "the FP talk" at work, and
then publicly own your mistakes
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Real-talk takeaways
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
We could write all this off as
symptoms of:
𝝺 Inexperience
𝝺 Lack of technical leadership from me
𝝺 Obviously not the right paths — so incompetence?
𝝺 I hope not; I think it's deeper
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Most things in life need to be
tended to
𝝺 our relationships
!
𝝺 our mental and physical health
"
𝝺 our gardens
$
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Paths can be accidentally
created, too
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
Some issues and failures that got
me here:
1. Persistent imposter syndrome
2. Feeling I just need to ship features and look out for myself
3. Not taking responsibility for a path I helped create
4. Not tending to things that needed tending to
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
But all is not lost!
The core tenets of FP seem to remain:
𝝺 Immutability
𝝺 Purity
𝝺 Moving effects to the conceptual edge of an application
𝝺 Very few classes and inheritance (React & web components
don't count), map/filter/reduce, etc.
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
The main point
Remember that the choices we do
and don't make significantly shape
our futures, so if you end up
somewhere, make sure you got there
on purpose.
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
That's it!
:q!
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
How to Lose FP at Work
web !" rwp.im
github !" rpearce
email !" me@robertwpearce.com
tweeter !" @RobertWPearce
@RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup

More Related Content

Similar to How to Lose Functional Programming at Work

Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scalascalaconfjp
 
Ruby on Rails 3.1: Let's bring the fun back into web programing
Ruby on Rails 3.1: Let's bring the fun back into web programingRuby on Rails 3.1: Let's bring the fun back into web programing
Ruby on Rails 3.1: Let's bring the fun back into web programingBozhidar Batsov
 
OOScss Architecture For Rails Apps
OOScss Architecture For Rails AppsOOScss Architecture For Rails Apps
OOScss Architecture For Rails AppsNetguru
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaKonrad Malawski
 
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018Davide Cerbo - Kotlin loves React - Codemotion Milan 2018
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018Codemotion
 
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)ruthmcdavitt
 
Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Holden Karau
 
freeCodeCamp Tokyo meetup 19
freeCodeCamp Tokyo meetup 19freeCodeCamp Tokyo meetup 19
freeCodeCamp Tokyo meetup 19健太 田上
 
Alpine academy apache spark series #1 introduction to cluster computing wit...
Alpine academy apache spark series #1   introduction to cluster computing wit...Alpine academy apache spark series #1   introduction to cluster computing wit...
Alpine academy apache spark series #1 introduction to cluster computing wit...Holden Karau
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)jeffz
 
Seattle useR Group - R + Scala
Seattle useR Group - R + ScalaSeattle useR Group - R + Scala
Seattle useR Group - R + ScalaShouheng Yi
 
Concurrecy in Ruby
Concurrecy in RubyConcurrecy in Ruby
Concurrecy in RubyVesna Doknic
 
State management in a GraphQL era
State management in a GraphQL eraState management in a GraphQL era
State management in a GraphQL erakristijanmkd
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Overview Of Parallel Development - Ericnel
Overview Of Parallel Development -  EricnelOverview Of Parallel Development -  Ericnel
Overview Of Parallel Development - Ericnelukdpe
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 

Similar to How to Lose Functional Programming at Work (20)

Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
Ruby on Rails 3.1: Let's bring the fun back into web programing
Ruby on Rails 3.1: Let's bring the fun back into web programingRuby on Rails 3.1: Let's bring the fun back into web programing
Ruby on Rails 3.1: Let's bring the fun back into web programing
 
OOScss Architecture For Rails Apps
OOScss Architecture For Rails AppsOOScss Architecture For Rails Apps
OOScss Architecture For Rails Apps
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018Davide Cerbo - Kotlin loves React - Codemotion Milan 2018
Davide Cerbo - Kotlin loves React - Codemotion Milan 2018
 
Y U NO CRAFTSMAN
Y U NO CRAFTSMANY U NO CRAFTSMAN
Y U NO CRAFTSMAN
 
Effective Object Oriented Design in Cpp
Effective Object Oriented Design in CppEffective Object Oriented Design in Cpp
Effective Object Oriented Design in Cpp
 
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
 
Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018
 
freeCodeCamp Tokyo meetup 19
freeCodeCamp Tokyo meetup 19freeCodeCamp Tokyo meetup 19
freeCodeCamp Tokyo meetup 19
 
Alpine academy apache spark series #1 introduction to cluster computing wit...
Alpine academy apache spark series #1   introduction to cluster computing wit...Alpine academy apache spark series #1   introduction to cluster computing wit...
Alpine academy apache spark series #1 introduction to cluster computing wit...
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
Seattle useR Group - R + Scala
Seattle useR Group - R + ScalaSeattle useR Group - R + Scala
Seattle useR Group - R + Scala
 
Concurrecy in Ruby
Concurrecy in RubyConcurrecy in Ruby
Concurrecy in Ruby
 
State management in a GraphQL era
State management in a GraphQL eraState management in a GraphQL era
State management in a GraphQL era
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Overview Of Parallel Development - Ericnel
Overview Of Parallel Development -  EricnelOverview Of Parallel Development -  Ericnel
Overview Of Parallel Development - Ericnel
 
Loom and concurrency latest
Loom and concurrency latestLoom and concurrency latest
Loom and concurrency latest
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 

More from Robert Pearce

Some Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.jsSome Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.jsRobert Pearce
 
A Path to Point-Free JavaScript
A Path to Point-Free JavaScriptA Path to Point-Free JavaScript
A Path to Point-Free JavaScriptRobert Pearce
 
From Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data TypesFrom Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data TypesRobert Pearce
 
hakyll – haskell static site generator
hakyll – haskell static site generatorhakyll – haskell static site generator
hakyll – haskell static site generatorRobert Pearce
 
Behaviour & Your Team
Behaviour & Your TeamBehaviour & Your Team
Behaviour & Your TeamRobert Pearce
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with reactRobert Pearce
 
React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015Robert Pearce
 
JavaScript 101 - Class 2
JavaScript 101 - Class 2JavaScript 101 - Class 2
JavaScript 101 - Class 2Robert Pearce
 
JavaScript 101 - Class 1
JavaScript 101 - Class 1JavaScript 101 - Class 1
JavaScript 101 - Class 1Robert Pearce
 

More from Robert Pearce (10)

Some Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.jsSome Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.js
 
A Path to Point-Free JavaScript
A Path to Point-Free JavaScriptA Path to Point-Free JavaScript
A Path to Point-Free JavaScript
 
From Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data TypesFrom Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data Types
 
hakyll – haskell static site generator
hakyll – haskell static site generatorhakyll – haskell static site generator
hakyll – haskell static site generator
 
FP in JS-Land
FP in JS-LandFP in JS-Land
FP in JS-Land
 
Behaviour & Your Team
Behaviour & Your TeamBehaviour & Your Team
Behaviour & Your Team
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with react
 
React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015
 
JavaScript 101 - Class 2
JavaScript 101 - Class 2JavaScript 101 - Class 2
JavaScript 101 - Class 2
 
JavaScript 101 - Class 1
JavaScript 101 - Class 1JavaScript 101 - Class 1
JavaScript 101 - Class 1
 

Recently uploaded

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Recently uploaded (20)

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

How to Lose Functional Programming at Work

  • 1. How to Lose FP at Work If you're looking to lose functional programming at work, here are a bunch of mistakes I've made on JS-heavy web teams over the years that can help you do the same! /s web !" rwp.im github !" rpearce email !" me@robertwpearce.com tweeter !" @RobertWPearce @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 2. About me 𝝺 Work at Articulate (articulate.com / rise.com) doing web dev work (heaps of accessibility work, too) 𝝺 12 years experience in the web world 𝝺 Enjoy Nix( ⚙ ), Haskell(λ), Rust( " ), Elixir( ), and even Go( ) on the side 𝝺 Was writing the Ramda Guide (ramda.guide), but life intervened, and I may strip it for parts 𝝺 Perpetual beginner-/intermediate-level FP practitioner 𝝺 Am a dad with another on the way! @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 3. Disclaimers/Heads up 𝝺 This backwards-style talk will be sarcastic, snarky, and cringey 𝝺 The examples are more JS-oriented, but the commentary is mostly universal 𝝺 The examples are all my examples and personal work-related head-canon; this should not reflect poorly on my colleagues nor my employer 𝝺 The slides aren't shouting at you — they're shouting at me @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 4. "Do"s and "Don't"s @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 5. Don't have static type checking @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 6. 𝝺 No TypeScript 𝝺 No Flow 𝝺 No ReasonML 𝝺 No Elm 𝝺 No (insert language with static type checking that compiles to JS) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 7. const processData = composeP(syncWithBackend, cleansePII, validateData) !" * What arguments and their types are expected here? !" !" * If each function is written like this, how can !" one suss out what data are flowing where? !" !" * How hard is this going to be to debug? !" Use this everywhere: `(x) !# (console.log(x), x)` So the point-free style is the problem? Not so fast… @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 8. async function processData(data) { await validateData(data) const cleansedData = cleansePII(data) await syncWithBackend(cleansedData) return data } !" or for the Promise-chainers… const processData = data !# validateData(data) .then(cleansePII) .then(syncWithBackend) .then(() !# data) !" ! Are these any clearer? Y/n? ¯_(ツ)_/¯ @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 9. Don't use well-known documentation tools @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 10. 𝝺 No jsdoc 𝝺 …are there any other JS contenders? @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 11. Deprive your team of this clarity and helpful auto-completion: /** * @typedef {Object} ReportingInfo * @property {("light"|"dark")} userTheme - Current user's preferred theme * @property {string} userName - Current user's name * @property {UUID} postId - The current post's ID !" /** * Validates that the reporting data (current user site prefences and post info) * is OK, removes personally identifiable information, syncs this info with the * backend, and gives us back the original data. * * @param {ReportingInfo} data - The current user's site preferences and post info * @returns {Promise<ReportingInfo>} - The original reporting data !" const processData = data !# { !$ … !" } @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 12. Don't properly train new and existing colleagues @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 13. "Here, go read all these posts and books, watch these videos, and let me know if you have any questions!" — Me @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 14. Don't bother getting the other engineering teams on board and rowing ! in the same direction @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 15. 𝝺 "If I build it, they will notice… right?" 𝝺 Idea: Lunch 'n learn about FP? ❌ 𝝺 Idea: Meet with other team leaders? @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 16. Do live by "Point-free or die" @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 17. "Think it's point-less? Go watch Point-Free or Die: Tacit Programming in Haskell and Beyond by Amar Shah" — Me @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 18. import { !", any, lt } from 'ramda' const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it anyLt0([1, 2, 3]) !# true — ugh… !# vs. the probably pretty simple… const anyLt0 = numbers !$ numbers.some(n !$ n < 0) anyLt0([0, 1, 2, 3]) !# false anyLt0([0, 1, 2, -1, 3]) !# true — looks good !# !# !# @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 19. import { !", any, lt } from 'ramda' const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it anyLt0([1, 2, 3]) !# true — ugh… !# vs. the probably pretty simple… const anyLt0 = numbers !$ numbers.some(n !$ n < 0) anyLt0([0, 1, 2, 3]) !# false anyLt0([0, 1, 2, -1, 3]) !# true — looks good !# ! should we resist eta-converting this?! !# !# @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 20. import { !", any, lt } from 'ramda' const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it anyLt0([1, 2, 3]) !# true — ugh… !# vs. the probably pretty simple… const anyLt0 = numbers !$ numbers.some(n !$ n < 0) anyLt0([0, 1, 2, 3]) !# false anyLt0([0, 1, 2, -1, 3]) !# true — looks good !# ! should we resist eta-converting this?! !# … !# @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 21. import { !", any, lt } from 'ramda' const anyLt0 = any(lt(0, !")) !# hint: this has a bug in it anyLt0([1, 2, 3]) !# true — ugh… !# vs. the probably pretty simple… const anyLt0 = numbers !$ numbers.some(n !$ n < 0) anyLt0([0, 1, 2, 3]) !# false anyLt0([0, 1, 2, -1, 3]) !# true — looks good !# ! should we resist eta-converting this?! !# … !# NOT ON MY WATCH @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 22. const any = fn !" array !" array.some(fn) const isLtN = x !" n !" x < n const isLt0 = isLtN(0) const anyLt0 = any(isLt0) anyLt0([1, 2, 3]) !# true — ugh; the bug is back @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 23. Real, but altered, example: const finishItems = compose( flip(merge)({ isDone: true, amtComplete: 100 }), over( lensProp('indexedObjects'), mapVals( compose( over(lensProp('indexedObjects'), mapVals(assoc('isDone', true))), assoc('isDone', true) ) ) ) ) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 24. Do prefer the wrong abstraction over the right duplication @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 25. "Prefer duplication over the wrong abstraction" — Sandi Metz’ RailsConf 2014 talk, All the Little Things @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 26. Instead… 1. Dilute core business logic to broad generalizations 2. Fail to understand category theory enough for this to be useful 3. Be the only one who knows how these abstractions work 4. Previously thorough PR-reviews now look like " " @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 27. Don't refactor old patterns that clearly don't work for the team @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 28. Do force functional patterns into a language that wasn't built for them @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 29. 𝝺 Recursive functions 𝝺Handle with trampolines if you really want them 𝝺 Cryptic stack traces thanks to currying and composing functions 𝝺Debugging functional by Brian Lonsdorf 𝝺Partially-applied (or curried) functions could obfuscate the JavaScript stack trace by Thai Pangsakulyanont 𝝺 No GHC-style fusing of .map(…).map(…).map(…) 𝝺 BYO algebraic data type libraries (they're well done, though) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 30. Do opaquely compose and sequence the entirety of your API endpoints and make them hard to debug @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 31. On the surface, this isn't so difficult to read… @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 32. !" handler for POST /posts import { createPost } from 'app/db/posts' import { authenticateUser, authorizeUser } from 'app/lib/auth' import { trackEvent } from 'app/lib/tracking' const validateRequestSchema = payload !# { !$ … !% } export const handleCreatePost = curry(metadata !# pipeP( authenticateUser(metadata), authorizeUser(metadata), validateRequestSchema, createPost(metadata), tapP(trackEvent('post:create', metadata)), pick([ 'id', 'authorId', 'title' ]) ) ) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 33. Did you catch or wonder about these? 𝝺 handleCreatePost expects 2 arguments? 𝝺 authenticateUser ignores the 2nd curried parameter sent to it? How would you? 𝝺 Does trackEvent receive the payload passed through or the result of the createPost() fn? Let's try something else… @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 34. export async function handleCreatePost(metadata, payload) { await authenticateUser(metadata) await authorizeUser(metadata, payload) await validateRequestSchema(payload) const post = await createPost(metadata, payload) await trackEvent('post:create', metadata, post) return { id: post.id, authorId: post.authorId, title: post.title, } } @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 35. ✅ Not forcing different arity functions into a pipeline pattern ! But if you want to make things trickier for people, go with the first approach @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 36. Do recreate imperative, procedural programming while calling it "declarative" @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 37. const setBookReadPercentByType = (contentType, statusObject) !" assoc( 'readPercent', pipe( prop('subItems'), values, filter(propEq(contentType, 'chapter')), length, flip(divide)(compose(length, keys, prop('subItems'))(statusObject)), multiply(100), Math.round )(statusObject), statusObject ) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 38. Do have 8+-ish different patterns for function composition @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 39. ! These 4, plus Promisified versions of each, plus combinations of them all used at once; doesn't include ramda's even more abstract composeWith and pipeWith !" compose (plus composeP for Promises) const getHighScorers = compose( mapProp('name'), takeN(3), descBy('score') ) !" pipe (plus pipeP for Promises) const getHighScorers = pipe( descBy('score'), takeN(3), mapProp('name') ) !" composeWithValue const getHighScorers = players !# composeWithValue( mapProp('name'), takeN(3), descBy('score'), players ) !" pipeWithValue (plus pipePWithValue for Promises) const getHighScorers = players !# pipeWithValue( players, descBy('score'), takeN(3), mapProp('name') ) @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 40. Do make yourself one of the few who can debug algebraic data types during midnight incidents @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 41. Ensure your team is surprised by all of the following words when debugging or altering your code in the pursuit of their own tasks: 𝝺 Task, Maybe, Either, Result, Pair, State 𝝺 bimap 𝝺 chain 𝝺 bichain 𝝺 option 𝝺 coalesce 𝝺 fork 𝝺 sequence 𝝺 ap 𝝺 map — and I don't mean Array.prototype.map, nor a new Map(), nor a key/value object @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 42. Do suggest, on PRs, that colleagues completely refactor what they've done to fit your functional style @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 43. "What you have here works great, but what could this look like if we flipped all the function arguments around, removed all these intermediate variables and if/else if/elses, and mapped these operations over an Either?" — Me @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 44. "I noticed you're explicitly constructing these objects in their functions. If you were to use <UTILITY-FUNCTION>, you could declare the shape of your outputted object and use functions as the values to look up or compute each value given some data." — Me @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 45. Ok, last ones! @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 46. Do sow imposter syndrome in others and exclude them by sharing non- beginner FP articles @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 47. Do Do keep writing code using FP tools even when nobody else on the team is @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 48. Do achieve peak perceived passive- aggression by getting tired and commenting PRs with emojis @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 49. Do have "the FP talk" at work, and then publicly own your mistakes @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 50. Real-talk takeaways @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 51. We could write all this off as symptoms of: 𝝺 Inexperience 𝝺 Lack of technical leadership from me 𝝺 Obviously not the right paths — so incompetence? 𝝺 I hope not; I think it's deeper @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 52. Most things in life need to be tended to 𝝺 our relationships ! 𝝺 our mental and physical health " 𝝺 our gardens $ @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 53. Paths can be accidentally created, too @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 54. Some issues and failures that got me here: 1. Persistent imposter syndrome 2. Feeling I just need to ship features and look out for myself 3. Not taking responsibility for a path I helped create 4. Not tending to things that needed tending to @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 55. But all is not lost! The core tenets of FP seem to remain: 𝝺 Immutability 𝝺 Purity 𝝺 Moving effects to the conceptual edge of an application 𝝺 Very few classes and inheritance (React & web components don't count), map/filter/reduce, etc. @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 56. The main point Remember that the choices we do and don't make significantly shape our futures, so if you end up somewhere, make sure you got there on purpose. @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 57. That's it! :q! @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup
  • 58. How to Lose FP at Work web !" rwp.im github !" rpearce email !" me@robertwpearce.com tweeter !" @RobertWPearce @RobertWPearce | rwp.im | 2023-01-24 Auckland Functional Programming Meetup