[Haskell-cafe] Investing in languages (Was: What isyourfavouriteHaskell "aha" moment?)
Alexey Raga
alexey.raga at gmail.com
Mon Jul 16 11:24:25 UTC 2018
I actually lost interest, because you are kind of trying to tell me that
because of your lack of _familiarity_ with monads, _my_ benefits do not
count. I cannot agree with this statement and with this approach.
But since there were questions, I'll answer and do some small clarification.
> I asked because never tried Eta. So, if you are right, seems no reasons
to develop Eta...
I am not sure why you are bringing Eta as an example to this discussion
just to point later that you have no experience with it.
The point of Eta is to run Haskell on JVM. Haskell as of GHC, and not some
hypothetical hybrid language (that would be Scala). If you want a decent
language, and you must run on JVM then you use Eta. If you don't need to
run on JVM - you don't use Eta.
> No better definition then original:
https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions
You see, they are different.
Now it is your turn to read this link. The second sentence on that link
says:
"They can be used to provide a convenient syntax for *monads*, a functional
programming feature that can be used to manage data, control, and side
effects in functional programs."
The emphasis on _monads_ isn't mine, it is original. The computation
expressions are _monadic_ (when they obey laws, but that link doesn't say
anything about laws, unfortunately).
> Something like this: user?.Phone?.Company?.Name??"missing"; ?
Still no.
> It does not force you to isolate state change in one place with explicit
control, it only
marks place where it happens.
processAttack :: (MonadState s m, HasBpsCounters s) => Attack -> m Result
No benefits for you, tons of benefits for me: I guarantee that this
function can only be called if there is access to some BPS counters. I
guarantee that this function, and whatever if uses inside itself, can never
touch or even look at anything else in my state. I can guarantee that it
doesn't cause any other effects like it doesn't call something which calls
something which prints to console or writes to DB. And that if during code
evolution/refactoring someone does something like that, then it won't
compile.
> If I add “print” for debug purpose in some subroutines, will they become
buggy? No.
Then you add this code inside a transaction and voila - yes, you do have a
bug.
In fact, my colleague who used to work at Nasdaq, had a story about exactly
this: Once upon a time there was a beautiful code that lived in a
transaction. Then someone accidentally introduced a side effect to one of
the functions. This function was called from something within that
transaction. The bug was noticed after some time when it has done some
damage.
In Haskell, you can't do IO in STM, so that wouldn't be possible.
> Haskell also does not guard you to mutate this state anywhere in the
application.
I think my example above proves otherwise: in Haskell, I can granularly
control who can update which part of the state, which makes your statement
invalid.
> monads have value, but it's small ... their value in other languages is
super-small
Again, a VERY bold statement I have to disagree with, once again.
F# workflows are monadic, C# LINQ is precisely modelled by E. Meijer as a
list monad. They add great value.
With this, I rest my case, thanks for the discussion.
Regards,
Alexey.
On Mon, Jul 16, 2018 at 5:45 PM PY <aquagnu at gmail.com> wrote:
>
> > So I think if you don't see anybody explicitly mentioning spaghetti
> > issues with State that's for some people it's just hiding in plain
> > sight and they either aren't consciously aware of it, or find that
> > area so self-explaining that they do not think they really need to
> > explain that.
> >
> IMHO State monad solution is orthogonal to my point. It does not force
> you to isolate state change in one place with explicit control, it only
> marks place where it happens. This info is needed to compiler, not to
> me. For me - no benefits. Benefit to me - to isolate changing, but with
> State I can (and all of us do it!) smear change points throughout the
> code. So, my question is: what exact problem does solve State monad?
> Which problem? Mine or compiler? Haskell pure lambda-only-abstraction
> limitation? OK, if we imagine another Haskell, similar to F#, will I
> need State monad yet? IMHO - no. My point is: State monad is super, in
> Haskell, and absolutely waste in other languages. I will isolate
> mutability in another manner: more safe, robust and controllable. Recap:
> 1. State monad allows you to mark change of THIS state, so you can easy
> find where THIS state is changing (tracking changes)
> 2. Singleton with FSM allows you to *control* change and to isolate all
> change logic in one place
>
> 1st allows spaghetti, 2nd - does not. 2nd force you to another model:
> not changes, but change requests, which can return: "not possible". With
> Haskell way the check "possible/not possible" will happen in locations
> where you change state in State monad: anywhere. So, my initial point
> is: State monad is about Haskell abstraction problems, not about
> developer problems.
>
> > Sorry, but that's not what OO is about.
> > Also, I do not think that you're using general FSMs, else you'd be
> > having transition spaghetti.
> To be precise, then yes, you are right. But such model forces me more,
> then monadic model. When you create singleton "PlayerBehavior", and have
> all setters/getters in this singleton and already check (in one place!)
> changes - next step is to switch from checks to explicit FSM - in the
> same place. Haskell nothing offers for this. You *can* do it, but monads
> don't force you and they are about Haskell problems, not mine.
> Motivation of State monad is not to solve problem but to introduce state
> mutability in Haskell, this is my point. OK, State monad has helpful
> side-effect: allows to track change of concrete THIS state, but I can do
> it with my editor, it's more valuable to Haskell itself, then to me,
> because no problem to mutate state: Haskell allows it, Haskell also does
> not guard you to mutate this state anywhere in the application.
>
> I'm agree with you 100%. My point is related to accents only, my thesis
> is: monads have value, but it's small, it's justified in Haskell with
> its limitation to one abstraction, but I don't need monads in other
> languages, their value in other languages is super-small (if even
> exists). So, motivation of monads introduction (for me, sure, I'm very
> subjective) is to workaround Haskell model, not to make code more safe,
> I'm absolutely sure: monads nothing to do with safety. It's like to use
> aspirin with serious medical problem :)
>
> > Let me repeat: What you call a "message" is just a standard
> > synchronous function call. The one difference is that the caller
> > allows the target type to influence what function gets actually
> > called, and while that's powerful it's quite far from what people
> > assume if you throw that "message" terminology around.
> I mentioned Erlang early: the same - you send message to FSM which will
> be lightweight process. Idea of agents and messages is the same in
> Smalltalk, in QNX, in Erlang, etc, etc... So, "message" does not always
> mean "synchronous call". For example, QNX "optimizes" local messages, so
> they are more lightweight in comparison with remotely messages (which
> are naturally asynchronous). But "message" abstraction is the same and
> is more high-level then synchronous/asynchronous dichotomy. It allows
> you to isolate logic - this is the point. Haskell nothing to do with it:
> you smear logic anywhere. But now you mark it explicitly. And you have
> illusion that your code is more safe.
>
> > But that's not the point. The point is that Haskell makes it easy to
> > write non-spaghetti.
>
> How? In Haskell I propagate data to a lot of functions (as argument or
> as hidden argument - in some monad), but with singleton+FSM - you can
> not do it - data is hidden for you, you can only *call logic*, not
> *access data*. Logic in Haskell is forced to be smeared between a lot of
> functions. You *CAN* avoid it, but Haskell does not force you.
>
> > BTW you have similar claims about FSMs. Ordinarily they are spaghetti
> > incarnate, but you say they work quite beautifully if done right.
> > (I'm staying sceptical because your arguments in that direction didn't
> > make sense to me, but that might be because I'm lacking background
> > information, and filling in these gaps is really too far off-topic to
> > be of interest.)
>
> I respect your position. Everybody has different experience, and this is
> basically very good!
>
> > We often repeat this: “side-effects”, “tracks”, “safe”. But what does
> > it actually mean? Can I have side-effects in Haskell? Yes. Can I mix
> > side-effects? Yes. But in more difficult way than in ML or F#, for
> > example. What is the benefit?
> >
> > That it is difficult to accidentally introduce side effects.
> > Or, rather, the problems of side effects. Formally, no Haskell program
> > can have a side effect (unless using UnsafeIO or FFI, but that's not
> > what we're talking about here).
>
> Actually if we look to this from high-level, as to "black box" - we see
> that it's truth. Haskell allows to have them, to mix them but in
> different manner.
>
> > Yes they will. Some tests will fail if they expect specific output. If
> > the program has a text-based user interface, it will become unusable.
>
> And wise-versa: if I will remove "print" from such tests and add "pure"
> - they can fail too. IMHO purity/impurity in your example is related to
> expected behavior and it violation, not to point that "more pure - less
> bugs". Pure function can violate its contract as well as impure.
>
> > Yes they will become buggy. You'll get aliasing issues. And these are
> > the nastiest thing to debug because they will hit you if and only if
> > the program is so large that you don't know all the data flows
> > anymore, and your assumptions about what might be an alias start to
> > fall down. Or not you but maybe the new coworker who doesn't yet know
> > all the parts of the program.
> > That's exactly why data flow is being pushed to being explicit.
>
> So, to avoid this I should not mix read/write monads, to avoid RWST. In
> this case they should be removed from the language. And monad
> transformers too. My point is: there is some misunderstanding - I often
> listen "side-effects are related to errors", "we should avoid them",
> "they leads to errors", etc, etc, but IMHO pure/impure is needed to FP
> language compiler, not to me. This is the real motto. Adding of
> side-effects does not lead to bugs automatically. Mostly it does not.
> More correct is to say: distinguish of pure/impure code is better to
> analyze the code, to manipulate with it, to transform it (as programmer
> I can transform F# code *easy because no monads*, in Haskell *compiler*
> can transform code easy *because monads*). More important argument for
> me is example with Free monads. They allows to simulate behavior, to
> check logic without to involve real external actions (side-effects).
> Yes, OK, this is argument. It's not explicitly related to buggy code,
> but it's useful. It remember me homoiconic Lisp code where code can be
> processed as data, as AST.
>
> Actually, I had a big interesting discussion in my company with people
> which does not like FP (the root why I become to ask such questions to
> himself). And I got their arguments. I tried to find solid base of mine.
> But currently I see that I like Haskell solutions itself, and I can not
> show concrete examples where they are needed in real world, without
> Haskell specific limitations. I know that those limitations lead to slow
> compilation, to big and complex compiler, I can not prove that
> side-effects means "lead to error", or (more interesting) that it's bad
> to separate side-effects from each other. F#, ML, Lisps have "do-" block
> and no problem with it. They don't need transformers to mix 2 different
> effects in one do-block. If you can prove that this decision leads to
> bugs and Haskell solution does not: it will be bomb :) I think, will be
> a lot of people in CS which will not agree with you ever.
>
> ---
> Best regards, Paul
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180716/4ea90bb2/attachment-0001.html>
More information about the Haskell-Cafe
mailing list