Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Although true; I'm not sure much of that provides clarity. Eg, "Your entire program is ... one new huge instruction" - that is true of any program, and it doesn't sound like a useful abstraction for reasoning about programs. The idea that getChar returns an instruction rather than a character is similarly not an obvious improvement from getChar() returning a character. It is quite subtle for someone to complain that getChar() returning a char is suboptimal.

Everything I've seen is monads are confusing because they solve a problem imperative languages don't think they have. As the article points out,

  function getDisplayPictureFromId(id) { 
    const user = getUser(id)
    if (!user) return
    const profile = getProfile(user)
    if (!profile) return
    return getDisplayPicture(profile)
  }
is totally fine and idiomatic in most imperative languages. Once a programmer starts chaining functions together (as functional programmers are wont to do) then the "if (!user) return" become a substantial blocker that needs a solution - which leads very quickly to monads and abstracting away IO.


That's not fine and idiomatic in any language I know.

This would be:

    function getDisplayPictureFromId(id) {
        return getUser(id)?.profile?.displayPicture
    }
If the language does not have the null-safe operator '?.' you just write it:

    function nullSafe(obj, callback) {
        if (obj) {
            return callback(obj)
        }
        return null
    }
    function getDisplayPictureFromId(id) {
        return nullSafe(getUser(id),
            (user) => nullSafe(user.profile,
                (profile) => profile.displayPicture)
        ))
    }
Not as nice in this case, but with a few similar functions for composing other functions, you achieve similar benefits to Monads without having the complexity of higher-kinded types.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: