News for hackers. Stuff that matters.
Re:If monads are the solution, what is the problem? by tathougies on Monday July 30, 2018 @02:33PM (#17646793)
After many years of Haskell, I was playing around in C the other day for fun. I'm writing low-level network code, and my code looks like this.

int err = socket(...) if ( err < 0 ) { do_something; }

err = listen(...) if ( err < 0 ) { do_something; }

Haskell's bind operator >>= makes abstracting this really simple. I wish I had it in C.

Re:If monads are the solution, what is the problem? by CodexArcanum on Monday July 30, 2018 @05:09PM (#17648065)
I hate to be "that guy" but take a look at Rust if you haven't. It's pretty close to C but incorporates a lot of functional-style type magic. Your particular example is very explicitly supported by the `Result` type (which is an error-specific version of Haskell's `Either` type). It also has some syntax sugar and macro usage to make working with error types pretty simple.
Re:If monads are the solution, what is the problem? by tathougies on Monday July 30, 2018 @07:01PM (#17648978)
Rust is great, but not appropriate for my C use case. I did consider it, and would use it for other systems level stuff. This particular project is very close to the metal, and I want to use C and assembler. But yeah, if it was any more complicated, I would use rust. Rust is pretty great.
Re:If monads are the solution, what is the problem? by xamuel on Monday July 30, 2018 @04:27PM (#17647708)
Could you elaborate? As a C guy, I'm interested what you think would be simpler than that simple code you posted. Structurally, what you just posted (minus the details about what "socket" and "listen" mean) could be understood by a child. I'm skeptical the corresponding Haskell >>= construction would be so understandable.
Re:If monads are the solution, what is the problem? by tathougies on Monday July 30, 2018 @04:43PM (#17647842)
In Haskell, the 'if (err) { ... }' parts could be factored out into a new bind operator for a new monad stack. Then, you don't have to write these checks every single time. The do notation is automatically converted into the corresponding monadic code, and the algebraic monad laws guarantee that the meaning of the code is preserved.

For example, for the `if (err) {...}` cases, this is just the `ExceptT` monad transformer.

With regard to understandability, using error throwing code in Haskell is really easy. Implementing it is slightly more difficult, but so is implementing a C compiler. I mean, we shouldn't judge the utility of a thing based on whether the implementation of the thing could be understood by a child. By that measure, children would be incapable of using facebook, because they could not build it.

Re:If monads are the solution, what is the problem? by xamuel on Monday July 30, 2018 @05:58PM (#17648494)
So what would the above code actually look like, in your world?

>you don't have to write these checks every single time

But in real-world applications, the way you react to errors would differ from function to function. Some functions would print a notification to a logfile and return early. Some would terminate the program and send an email to an admin. Some would activate a red "offline" indicator somewhere in a program.

Re:If monads are the solution, what is the problem? by tathougies on Monday July 30, 2018 @07:06PM (#17649013)
In haskell? I'd construct an API that could be used like the following. This looks like the code we write at the place i work at:

     runService=
       s <- note SocketConnectionError $ socket AF_INET ...
       note CouldNotListen $ listen s 5
       note CouldNotBind $ bind s ...
       
       forever $ do
          client <- note CouldNotAccept $ accept s
          response <- serveRequest client
          ...
The signatures of socket, bind, etc, would look like (for example):

    socket :: ExceptT SocketError IO Int
    listen :: Int -> Int -> ExceptT ListenError IO ()
Then, at top level

    main = runExceptT runService >>=
           either handleError pure

    handleError (SocketConnectionError rsn) = <try again, maybe>
    handleError ...
The key here is that error handling is factored out. The 'runService' function expresses concisely all the steps taken, and the entire concern of error handling is factored out into the 'handleError' function, whose behavior I can actually change based on what I may want. In a C implementation, changing error handling strategies, would mean passing some kind of flag in (you could rebuild exceptions using setjmp/longjmp, but meh).
Re:If monads are the solution, what is the problem? by lmm on Monday July 30, 2018 @05:56PM (#17648478)
Children aren't born knowing C, and people who learn functional first don't tend to find it any harder. (If anything it's easier, since the meaning of "=" in Haskell is much closer to its usual meaning than the meaning in C).
Re:If monads are the solution, what is the problem? by red75prime on Tuesday July 31, 2018 @03:34AM (#17651251)
> people who learn functional first don't tend to find it any harder

Do you have a source? I have a vague recollection of a paper doing some research on that, but cannot find it. If I'm not mistaken, results weren't that clear cut.

Re:If monads are the solution, what is the problem? by tathougies on Monday July 30, 2018 @07:02PM (#17648982)
Yeah, I agree. Functional languages are often more intuitive to beginners. My pet theory is that the reason CS people tend to be somewhat 'odd' is that most people do not think imperatively, so when imperative programming is propped up as the gateway, it screens out people who would otherwise flourish in the field.
Re:If monads are the solution, what is the problem? by magicalhippo on Tuesday July 31, 2018 @09:52AM (#17653095)
> most people do not think imperatively

When trying to solve a problem by thinking it through, don't most people think imperatively? Ie by a sequence of steps (statements) that modify the world around them (state) to reach the goal?

Re:If monads are the solution, what is the problem? by tathougies on Tuesday July 31, 2018 @10:34AM (#17653469)
I’m not a psychologist. I can’t talk about most people. I do not. I break problems down into sub problems and then think of how to combine results to achieve the answer. I repeat this until my subproblem is trivial. This lends well to the compositional approach of functional languages. Imperative languages require taking the extra step of scheduling. I think many people think like me but due to the prevalence of imperative languages, do not pursue cs.
Re:If monads are the solution, what is the problem? by magicalhippo on Tuesday July 31, 2018 @04:42PM (#17656902)
Well, scheduling is important. I can't connect my new phone to the computer until I've taken it out of the box it came in.

It feels like I'm leaning to the imperative side. When breaking down the problem into substeps, I'm already thinking about the sequencing which will later dictate the scheduling.

I've been teaching Scratch[1] to 11-13 year olds for a few years now, and most seem to pick it up pretty quick. However a few struggle (while still being motivated enough to keep trying). Would be interesting to see how it went with a functional Scratch version.

[1]: https://scratch.mit.edu/

Re:If monads are the solution, what is the problem? by lmm on Wednesday August 01, 2018 @04:29AM (#17660558)
> Well, scheduling is important. I can't connect my new phone to the computer until I've taken it out of the box it came in.

That's not scheduling, that's a data dependency which functional style handles very well. Imperative would be more like deciding you have to unpack the charger and then unpack the phone and then charge the phone, when in fact it's fine to unpack them in either order. http://www.lihaoyi.com/post/WhatsFunctionalProgrammingAllAbo... has an extended example.

Re:If monads are the solution, what is the problem? by magicalhippo on Wednesday August 01, 2018 @09:06AM (#17662094)
Good point, thanks for the correction.
Re:If monads are the solution, what is the problem? by tathougies on Wednesday August 01, 2018 @03:08PM (#17665883)
I think codeworld is a more functional alternative to scratch, although much less drag and drop. Check it out.. It's pretty fun! https://code.world/
Re:If monads are the solution, what is the problem? by dustingetz on Monday July 30, 2018 @08:17PM (#17649482)
C error checks are easy but not simple, you need enormous amounts of QA for every single change to know if you got it right (and then you still dont know)
Re:If monads are the solution, what is the problem? by vikiomega9 on Monday July 30, 2018 @04:15PM (#17647603)
:D I think go did a good job of internalizing this