Open tmichniewski opened 1 year ago
Thank you again for all of this! I’ll reply more as soon as I get to this part of the book during the rewrite process. Really, at this moment I don’t know if I’ll keep this content, but that’s when I’ll take a deep dive into it again.
Below I summarize a few observations after studing the examples of
State
monad.Firstly, I noticed that when we add some logs to
swing
,flatMap
, andmap
methods, then we notice that the sequence of operations infor expression
and after it is a bit surprising:Please notice that out of the whole
for expression
only the firstswing
and subsequentflatMap
gets called when we execute thefor expression
.In contrary, if we rephrase the
for expression
into direct series of calls toflatMap
andmap
:then we will see that all the calls to
swing
,flatMap
andmap
are executed instantly while computingstateWithNewDistance
. So, there is some mysterious lazy computation involved in thefor expression
.Secondly, the name of the monad is really misleading. When we reason about how it may work internally, we end up thinking that we have some value of "state" at hand and after some steps we find ourselve asking: "Hold on, what
state
are we talking about at the moment, the monadState
or the real state of typeS
represented by case classGolfState
". This is a real problem, because there are two "states".In my opinion, the monad should be renamed to something like
StateMonad
orStateUpdater
or even simplyUpdater
to make this type distinguishable from the real state being updated, which is of generic typeS
and in the application is represented byGolfState
.Thirdly, I started thinking what in reality we are trying to model by this monad, the real state or the act of updating the state. This is a serious question. This monad seems to pretend that it represents the act of updating the state. So this for expression:
might be treated as series of updating lambda functions like:
but then, this
for expression
on this mysterious monad might be treated as much simpler composition of those functions:which could also be later applied like the
State
monad is applied by calling therun
method. And also both (fgh
lambda function andState[GolfState, int]
) behave kind of lazy. Butfgh
lambda function, which is also pure, is much, much simpler to reason about and in fact much shorter, as it does not require implementingflatMap
andmap
methods and there is no automatic conversion offor expression
into series offlatmap
andmap
calls.Finally, comming back to the question, whether we want to model the state or the act of updating the state, and if we compare to the monad which was created earlier in the book, when the monad was the class which just encapsulated the Int value, then we could have concluded, that this earlier monad (commented as "What I need is a better State monad") was in fact a monad, which modelled the state, not the act of updating the state.
Moreover, it was pretty obvious what was going on and 100% of Scala developers could understand this code, while the allegedly "better" monad makes understandig of it much more difficult. It may seem initially, that it is more elegant, but when the problems appear (as pointed out at the beginning or if there are more states to update), then it is very difficult to debug it, because there is no Scala library for
for expression
and transition betweenfor expression
and calls toflatMap
andmap
is conducted behind the scene, as there is no trait of Monad (unless somebody usescats
).Concluding, the "better" State monad is something which makes complex what should be simple and it seems that someone forgot about such rules as KISS ("keep it simple"). Here, insted of 100% we end up in a situation that less than 1% of Scala developers is able to fully understand the concept of State monad. At least in presented version.