Skip to content

Commit 8d0d0a3

Browse files
committed
reframe part 2
1 parent 21d6661 commit 8d0d0a3

File tree

2 files changed

+80
-34
lines changed

2 files changed

+80
-34
lines changed

copy/entries/five-point-haskell-2.md

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,34 @@ errors through our types.
2323

2424
[Total Depravity]: https://blog.jle.im/entry/five-point-haskell-part-1-total-depravity.html
2525

26-
But, types don't only prevent bugs: they also help us in the process of
27-
designing and structure our programs! So, let's jump right into our second
28-
point in five-point Haskell: **Unconditional Election**!
26+
However, picking good structures, making invalid states unrepreentable, etc.
27+
can only go so far.
2928

30-
> Unconditional Election: The _structure_ of your types fully determine the
31-
> values and states it will ever take. Nothing at runtime can ever circumvent
32-
> this.
29+
Types aren't just about preventing bad behaviors. They're about designing good
30+
code. And there is one principle that helps guide this design by leveraging the
31+
unyielding properties of the universe _itself_ to take care of our fate, even
32+
when we are unable to structure our types well.
33+
34+
Let's jump into the second point in five-point Haskell: **Unconditional
35+
Election**!
36+
37+
> Unconditional Election: The power of the `forall` to elect or reprobate
38+
> instantiations and implementations through parametric polymorphism.
3339
>
34-
> Therefore, take advantage and design the structure of your _types_ to
35-
> anticipate the logic you want to model. The program is pre-destined before
36-
> you even write any functions.
40+
> Invariants and correctness are not based on the foreseen merits of the
41+
> structure of types you choose, or on runtime reflection and ad-hoc
42+
> polymorphim, but rather in the predestination of universal quantification.
43+
>
44+
> Therefore, surrender to your control to parametric polymorphism in all
45+
> things. In simple terms: add a type parameter.
46+
47+
<!-- > Unconditional Election: The _structure_ of your types fully determine the -->
48+
<!-- > values and states it will ever take. Nothing at runtime can ever circumvent -->
49+
<!-- > this. -->
50+
<!-- > -->
51+
<!-- > Therefore, take advantage and design the structure of your _types_ to -->
52+
<!-- > anticipate the logic you want to model. The program is pre-destined before -->
53+
<!-- > you even write any functions. -->
3754

3855

3956
<!-- ### Squished Pipeline -->
@@ -58,7 +75,7 @@ point in five-point Haskell: **Unconditional Election**!
5875
<!-- ```haskell -->
5976
<!-- pay :: Checkout -> IO Checkout -->
6077
<!-- pay c = case address c of -->
61-
<!-- Just addr -> do -->
78+
<!-- Just addr -> do -->
6279
<!-- tok <- processPayment (items c) addr -->
6380
<!-- pure $ c { payment = Just tok } -->
6481
<!-- Nothing -> -- uh.... -->

copy/entries/five-point-haskell.md

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,29 +109,49 @@ Theme: "Postmortems" of real world accidents, programming gore.
109109
* Use-after-free --- continuations, Acquire, ResourceT
110110
* Shotgun validation/parser inside database, accidentally save unvalidated
111111
data
112-
113-
TODO:
114-
115112
* Boolean blindness
116-
* Crash early: you're not going to catch every exception. don't use
117-
`SomeException` either.
118113

119114
Unconditional Election
120115
----------------------
121116

122-
Idea: The choice of the type's structure will fully determine the values
123-
allowed. Bad states are unrepresentable.
117+
<!-- Idea: The choice of the type's structure will fully determine the values -->
118+
<!-- allowed. Bad states are unrepresentable. -->
119+
120+
<!-- Theme: Type-Driven Development, Prase Don't Validate -->
121+
122+
<!-- * Boolean blindness/multiple Maybe issues -->
123+
<!-- * NonEmpty lists -->
124+
<!-- * State machine requires each step (GADT enforced?) -->
125+
<!-- * Authorization payloads -->
126+
<!-- * Higher-kinded data -->
127+
<!-- * Sized vectors -->
128+
129+
Idea: Parametrically polymorphic code will pre-destine what functions are
130+
possible. Take advantage of it to enforce invariants and what you can write,
131+
instead of using ie refinement types or postconditions.
132+
133+
Theme: Guessing game, what functions are allowed?
124134

125-
Theme: Type-Driven Development, Prase Don't Validate
135+
Be careful to not frame the programmer as the person who is electing the terms.
136+
Frame it as the type system electing the valid terms
126137

127-
* Boolean blindness/multiple Maybe issues
128-
* NonEmpty lists
129-
* State machine requires each step (GADT enforced?)
130-
* Authorization payloads
131-
* Higher-kinded data
132-
* Sized vectors
138+
Give away your free will -- just be elective! constraint is liberation.
133139

134-
* Can we do parametric polymorphism here?
140+
Oh that's the key: "Constraint is liberation"! it is not by works or foreseen
141+
faith! the more you surrender....the safer you are! principle of least
142+
strength! also can maybe combine with purity in multi-threaded. restrictions
143+
are better.
144+
145+
Principle of Least Strength
146+
147+
* Parametric polymorphism --- guess the implementation
148+
* `[Int] -> [Int]` vs `[a] -> [a]`
149+
* Compare with refinement types
150+
* higher-kinded data, parametric over functors
151+
* Subtyping via parametric polymorphism
152+
* Phantoms + parametric polymoirphism, restrictions, ST trick
153+
* Princple of least strength, Monad vs Applicative
154+
* typeclass-based limitation of functions
135155

136156
Limited Atonement
137157
-----------------
@@ -176,14 +196,23 @@ church encodings?
176196
Perseverance of the Saints
177197
---------------------------
178198

179-
Idea: Well-typed code will survive big refactoring
199+
Idea: Benefits of Immutability
200+
201+
* Immutability
202+
* Sharing --- all new data structures
203+
* Multi-threaded
204+
* Locks, STM
205+
206+
<!-- Idea: Well-typed code will survive big refactoring -->
207+
208+
<!-- Theme: Hands-on refactoring, seeing how changes propagate. Build on chained -->
209+
<!-- successive refactors -->
210+
211+
<!-- * String -> Sum Type/Enum -->
212+
<!-- * Add new constructor -->
213+
<!-- * Add new field to record -->
214+
<!-- * `ToJSON`/`Persist` change -->
215+
<!-- * Refactor "reason" to be owned by the sum type -->
216+
<!-- * Property tests to help it all out -->
180217

181-
Theme: Hands-on refactoring, seeing how changes propagate. Build on chained
182-
successive refactors
183218

184-
* String -> Sum Type/Enum
185-
* Add new constructor
186-
* Add new field to record
187-
* `ToJSON`/`Persist` change
188-
* Refactor "reason" to be owned by the sum type
189-
* Property tests to help it all out

0 commit comments

Comments
 (0)