3 ms·
I disagree that it's forcing learners to use advanced concepts. It's giving them syntax sugar and a fairly clear introductory explanation (IO is done only with
by yawaramin 9y ago
I disagree that it's forcing learners to use advanced concepts. It's giving them syntax sugar and a fairly clear introductory explanation (IO is done only with the `IO` type for safety reasons) and giving them all the capabilities of IO in other languages straight from day one.
Forgetting about types for a second, can you really say that `putStrLn "hello"` is harder to understand than `console.log("hello")`? Trust me when I say this, plenty of people have taught Haskell to kids and the result has always been that they pick it up easily. Programmers from other backgrounds worry away too much of their mental capacity thinking about monads. Stop worrying about it and just hack away.
- crimsonalucard 9y agoUnderstanding a pattern is different from copying a pattern. Our disagreement lies not with kids copying a pattern but with people fully comprehending the philosophy and true nature of the monad abstraction. This is not easy for a beginner. Allow me to elucidate: Here is a an example of a trivial operation in imperative programming that becomes a bit more complicated in Haskell: Create a function that prints everything in an array: naive implementation in haskell (won't work): printElements arrayOfStrings= map putStrLn arrayOfStrings main = printElements ["Hello", "World"] True implementation: printElements [] = return () printElements x:xs = (putStrLn x) >> (printElements xs) main = printElements ["Hello", "World"] The second implementation requires understanding of types and the IO monad while the first implementation is a naive and broken implementation that most people turn to when learning Haskell. It is not trivial to explain to a person why it must be done the second way... All of this and all we were doing was printing something to the console! It's too much! Monads aren't even a required part of functional programming. Haskell is not a great language to learn about functional programming.
- tome 9y agoActually the "true" implementation is printElements arrayOfStrings = traverse putStrLn arrayOfStrings main = printElements ["Hello", "World"] but the difference between map and traverse is sufficient for your point to still hold water.
- yawaramin 9y agoI think we would actually use `mapM_` rather than `traverse`.
- Retra 9y agoJava requires you to understand class and public static void main (and classpath crap) before you can print to console, but that doesn't seem too hard for anyone to learn.
- crimsonalucard 9y agoThe concept of an object is trivial compared to a monad. Objects in the computing world have real world equivalents. The real world equivalent of a monad is a burrito.
- Retra 9y agoThat is no way in which I can agree with any of that. An object is a rather poor analogy for a real world entity. Real objects don't need to have methods declared on them, they arise naturally from its state and from interactions with the state of other objects. Dogs don't have "wag tail" methods. Dogs don't have "name state" they are simply called names by people and have the facility to recognize their own name. And as a poor analogy, a monad is also quite trivial.
- crimsonalucard 9y agoObjects all have state and certain behaviors attributed to the object. In common OOP vernacular this is known as state and methods. A real world analogy is a ball that can bounce and also has a bounciness coefficient, the ability to bounce is the method and the bounciness coefficient is the state. This makes sense. A burrito is a monad. Explain this.
- yawaramin 9y agoThat's a good point. But it actually goes back to my previous point that we need to teach that multiple IO actions need to be sequenced together to guarantee proper order, hence you can't just map a print operation over a list of items--and in fact the type system prevents you from making that mistake. As I mentioned before, I would stick to the do notation syntax sugar; there's really no need to bring the symbolic operators into this: printElements [] = return () printElements (x:xs) = do putStrLn x printElements xs
- crimsonalucard 9y agodo notation sugars free variables which leads to more confusion and more complexity. It may not be idiomatic, but I avoid do notation for this reason. It's almost a backwards abstraction... if the functional style is really better... why create syntactical sugar to make haskell seem imperative? You guys are right on traverse or mapM though.
- yawaramin 9y agoYes, we have to walk a fine line here. The fact that do notation desugars to function calls in a complete deterministic way is nevertheless not easy to explain to learners. It's a judgement call but overall its benefits outweigh the drawbacks--IMO.