News for hackers. Stuff that matters.
Re:Learn Physics with Functional Programming by tome on Friday September 08, 2023 @03:19AM (#37430544)
> My point isn't that it errors. It's completely reasonable to expect even a beginner to do basic troubleshooting. My point is that the error specifically mentions monads.

Right, and the Python errors mention all sorts of things a beginner is not expected to understand, like "builtin_function_or_method". I don't think "understanding builtin_function_or_method" is required to write the Python and I don't think "understanding Monad" is required to write the Haskell.

> If our requirements changed to now read and sum an arbitrary number of inputs together, I'd expect a beginner could change the Python program to do so. I'm skeptical they could make the required changes to the Haskell version (without understanding monads).

Where do I have to "understand monads" to write this?

    main = do
      iters <- readLn
    
      let loop n total =
            if n == iters
            then print total
            else do
              x <- readLn
              loop (n + 1) (total + x)
    
      loop 0 0
I had to understand that in Haskell looping is done via recursion (which is mindbending initially, if you come from imperative programming), but I don't see that I had to understand monads. FWIW the Python that I'd write is

    def main():
        iters = input()
    
        total = 0
    
        for _ in range(iters):
            x = input()
            total += x
    
        print total
This is simpler. But I could write a Haskell version that uses an IORef to get roughly the same code structure as the Python.

    main2 = do
      iters <- readLn
    
      total <- newIORef 0
    
      for_ [1..iters] $ \_ -> do
        x <- readLn
        modifyIORef' total (+ x)
    
      theTotal <- readIORef total
    
      print theTotal
I would say this requires understanding the mutability/immutability distinction to know why we use an IORef at all (but you'd get that with OCaml[1] too) and it still requires understanding do notation, but I don't see that it requires "understanding monads"!

Now, if I were writing this for real I probably would use a version with a state monad transformer so it was

    main3 = do
      iters <- readLn
    
      total <-
        flip runStateT 0 $ for_ [1..iters] $ \_ -> do
          x <- lift readLn
          modify' (+ x)
    
      print total
That would require some understanding of monads so that you can understand how they are transformed with monad transformers!

[1] https://www.cs.cornell.edu/courses/cs3110/2018sp/l/14-mutabl...

There are no comments on this comment yet.