-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revisiting application structure #4
Conversation
Going sailing tomorrow, so published an initial version of this. Happy to update the attribution paragraphs if there's something else you think I should put there :) |
mechanical boilerplate. This behavior looks like it could be captured by a | ||
typeclass (or two). | ||
|
||
One of our engineers, [Moisés](https://twitter.com/1akrmn), who previously |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely not my credit to take! This approach was pretty much in place when I joined the team where I saw it. I believe @pepeiborra, @vapourismo and @adamse might have a better picture of the story behind it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I joined Strats in Jan 2017, the codebase was already making heavy use of type classes for individual effects, e.g. MonadTime
, MonadDelay
, MonadLog
, etc. but there was no solution to the n^2 problem. Monad transformers were providing instances for all the effects, relying on deriving to avoid as much boilerplate as possible. Alexis article takes this approach to the extreme.
I made the point that introducing a new effect class required adding it to the deriving lists of all N transformers, which made engineers unwilling to add effects. and the approach could not scale. My solution to this was the passthrough instance, which requires a MonadTransControl
transformer (or MonadtTrans
for non-scoped effects). Since all ReaderT
transformers are in MonadTransControl
by definition unless the environment mentions the base monad, the codebase quickly gravitates towards ReaderT
in order to avoid having to write instances manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the insight! Added it to the post and linked to your comment 🙌
Here's a draft of my thoughts on us going to the
MonadTransControl
approach for MTL.Here's TODOs:
MonadTransControl
vs onlyMonadTrans
?