Skip to content

Instantly share code, notes, and snippets.

@chefnobody
Last active August 31, 2020 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chefnobody/4466926c9cf37fc762672293b85ddc07 to your computer and use it in GitHub Desktop.
Save chefnobody/4466926c9cf37fc762672293b85ddc07 to your computer and use it in GitHub Desktop.
Notes from Brandon William's Finding Happiness in Functional Programming
https://www.youtube.com/watch?v=A0VaIKK2ijM
SEPARATION OF EFFECTS FROM PURITY
Part 1:
Isolation of side-effects
An expression is said to have a side-effect if its execution makes an observable change to the outside world.
The goal is to make side-effects understandable, not make them go away.
Ex:
Changing a label's text.
```
self.titleLabel.text = someText
```
Isolation of side-effects:
```
func update(text: String, forLabel: UILabel) {
label.text = text
}
...
update(text: user.name, forLabel: self.titleLabel)
```
Haskell, Purescript and even Elm offer "escape" hatches into which you can launch side effects.
Surfacing of co-effects
A co-effect is the "dual" of an effect.
What is duality?
If an effect is a change to the outside world after executing an expression
...then...
a co-effect is the state of the world that the expression needs in order to execute.
Sufacing of co-effects:
e.g. => Dependency Injection
Colin Barrett, Tomas Petricek
Effect/Co-effect Duality is what prevents easy testing.
- Execute your function
- Inspect the world and see what happened
In Haskell the escape hatch is the IO monad (which isn't popular?)
"Code to the interface you wish you had, not the interface you were given." - Stephen Celis
UIKit is a huge offender of effect/co-effect
Example: Storyboards
- Very thick abstraction layer
- Built for getting your feet wet, not for building long-living scalable programs
- Separates code from data. No way to model grids, fonts, colors, etc...
An interface we wish we had: Lenses
- Embrase immutability in a more user friendly way
Lenses
```
struct Project {
let creator: User
let id: Int
let name: String
}
```
An immutable struct whose properties can not be changed. Just a value type.
Every model gets a `lens` name space which then gets a Lens from the `Project` type to the value of the field:
```
Project.lens.name // => Lense<Project, String>
```
Every field becomes a Lens
A Lens is a pure version of a getter/setter. The Getter extracts the string, Setter replaces the name of the old string,
but returns a whole new Project.
Usage:
```
Project.lens.name .~ "Advanced Sw2ift" // => Project -> Project
```
Use fancy operators to interact w/ Lenses
```
project
|> Project.lens.name .~ "Advanced Swift"
```
Chaining, composability, completely extract out the two lenses.
```
project
|> Project.lens.name .~ "Advanced Swift"
|> Project.lens.creator.name .~ "Chris Eidhof"
```
UIKit Lenses
Lenses are getters/setters as pure functions.
```
UIView.lens.backgroundColor // => Lens<UIView, UIColor>
```
UIView.lens.backgroundColor .~ .redColor()
"You could lens-into ..."
Styling UIView is now composable through Lenses
```
func roundedStyle(cornerRadius: CGFloat) -> (UIView) -> UIView {
return UIView.lens.layer.cornerRadius .~ 4
<> UIView.lens.layer.maskToBoudns .~ true
}
view
|> roundedStyle(cornerRadius: 4)
|> UIView.lens.backgroundColor .~ .redColor()
```
... you could build an entire style guide like this...
- Allows you to develop a style guide applied anywhere
- Allows you to think as styles as independent things, composable, etc ....
PRINCIPLES WE DID NOT BENEFIT SO MUCH FROM:
- D.R.Y.
- S.R.P. - this is more of a personal opinion "Does this thing do too many things?"
- S.O.L.I.D -
- Objects. Never met an object that I liked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment