codependency
(co·de·pen·den·cy)
A morphism in the opposite category of Depop.
Principal engineer at Mercury. I've authored the Dhall configuration language, the Haskell for all blog, and countless packages and keynote presentations.
I'm a midwife to the hidden beauty in everything.
💖 @wiredaemon
feeling like i am finally starting to understand distributivity-flavored laws[1]. an xmas miracle
[1]: ie, laws that look kinda like f(x ⋆ y) = f(x) ⋅ f(y)
One interesting language design thread we've stumbled upon with Swift, but haven't fully developed, is the use of coroutines as an alternative to higher-order functions for building "control flow like" constructs. No slight against higher-order functions—as a singular language concept, they definitely pay for themselves in the expressivity they add—but in typed languages, whose type systems already have a tendency toward ever-growing complexity, function types are a particularly good complexity generator. Coroutines are definitely a more complex concept than functions, but I wanted to share some of my thoughts on how they have the potential to save complexity elsewhere, allowing for similar expressivity in extensible control flow constructs while requiring a less complex type system to manage the composition of effects within those constructs.
Specifically, go through the tutorial: https://hackage.haskell.org/package/pipes-4.3.16/docs/Pipes-Tutorial.html
My pipes package does exactly what the above chost describes and even comes with some elegant mathematical laws that fall out as a consequence of the implementation being inspired by category theory.
For example, if you model for loops using coroutines, you can derive three laws.
The first law (which is the "left identity" law) is:
for (yield x) f = f x
… which says that if you loop over a coroutine that yields once, it's the same as calling the body of the loop on the single value that was yielded.
The second law (the "right identity" law) is:
for s yield = s
… which says that if you loop over a coroutine and do nothing except re-yield each element then you get back the original coroutine.
The final law (the "associativity" law) is:
for s (\x -> for (f x) g) = for (for s f) g
… which says that any doubly-nested loop can be transformed an equivalent two-pass loop.
The correspondence to category theory becomes clearer if you define the following operator:
(f ~> g) x = for (f x) g
… because then the three laws become:
yield ~> f = f -- Left identity law
f ~> yield = f -- Right identity law
(f ~> g) ~> h = f ~> (g ~> h) -- Associativity law