4 ms·
Now you have the condescending tone! However, it appears you don't understand the IO monad. Programming using the IO monad is pure functional programming with f
by willtim 9y ago
Now you have the condescending tone! However, it appears you don't understand the IO monad. Programming using the IO monad is pure functional programming with full referential transparency. Please read Phil Wadler's paper, you will not understand this from that JavaScript snippet. The only backdoors are escape hatches like unsafePerformIO which are used for low-level libraries and FFI, they can be disabled with pragmas and/or compiler switches.
It is much harder to stay true to that definition using the other languages, multi-paradigm or not. That is why Haskell is so often mentioned in the context of FP.
- dmitriid 9y agoAs soon as you have side-effects (an IO is a side-effect) you can through your assumptions about "strict conformation to definition" out of the window: --- treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. --- > It is much harder to stay true to that definition using the other languages, multi-paradigm or not. I doesn't matter if it's "hard". Your argument was that "Only Haskell strictly conforms to that definition." No. Haskell conforms stricter. It doesn't mean that none of the other languages are not FP, or cannot be used to program in functional style. > That is why Haskell is so often mentioned in the context of FP. Yes. And the problem is that people treat the features that Haskell has as requirements to be considered a functional programming language. - Typeclasses/Liquid types/Dependent types are not FP - Pattern matching is not FP - Laziness is not FP - A whole bunch of anything else is not FP
- willtim 9y ago> As soon as you have side-effects (an IO is a side-effect) you can through your assumptions about "strict conformation to definition" out of the window Again, you are unfortunately quite wrong. You do not understand the IO Monad. No IO is ever performed in any code written inside the IO monad (unless using unsafePerformIO). Please take some time to fully understand Haskell before criticising it so openly on a public forum. Perhaps then it might not all seem rather pointless.
- dmitriid 9y agoSo, you're telling me that Haskell never does any output and never reads any input. In this case (an only in this case) would it strictly conform to FP definition.
- willtim 9y agoHaskell is used to wire-up the IO actions, they are then delivered to the runtime via the main definition. The runtime performs the IO actions.
- spion 9y agoIndeed Haskell the language doesn't do any IO. Instead, it creates a tuple containing * a description of the action to execute (e.g. read line from STDIN) * a function that will take the result of the previous action (e.g. the line) and return the next action to execute (e.g. writeLine) [readLine, \line -> writeLine(line)] This main action is just a description, the runtime itself takes it, does the actual IO described in the first part of this tuple, evaluates the second (function) part of the tuple with the result of that IO, receives a new pair of action/function, does the action's IO part, evaluates the new function and so on until it gets a nil (end of the "linked list" so to speak) You could imagine this as a linked list of actions, where the "link" is actually a pure function you call with the result of execution the first part to get the rest of the list (or nil to terminate). This is still pure because the action itself doesn't do anything. If you return an action from a function, it doesn't actually execute, its just a value to be interpreted. Does that make a real difference or is it just theoretical "purity"? Yes it does make a difference. For example, if you create two action values, you haven't actually run anything yet, just created descriptions of actions. You could put them in a list and create an action description that will tell the runtime to run them in parallel, for example using: https://hackage.haskell.org/package/parallel-io-0.3.3/docs/Control-Concurrent-ParallelIO-Global.html https://hackage.haskell.org/package/parallel-io-0.3.3/docs/C... ... or in sequence https://hackage.haskell.org/package/base-4.10.0.0/docs/Prelude.html#v:sequence https://hackage.haskell.org/package/base-4.10.0.0/docs/Prelu... For refactoring, it means that you can still take functions that return actions and substitute them with their values, e.g. if you have readItems 0 = return [] readItems n = do x <- readLine y <- readItems (n - 1) x :: y main :: IO items <- readItems 3 putStrLn "The first item is " ++ (head items) you could pull (readItems 3) out of main! read3Items = readItems 3 main :: IO items <- read3Items putStrLn ... and everything is exactly the same, since all you've pulled out is a description of an action. Equational reasoning (you can substitute an equation with its result) still works - which is great for refactoring!
- seagreen 9y agoYou're making some good points here. Neither category theory informed typeclasses nor laziness are required for pure functional programming (henceforth PFP). Up until recently Haskell was the only PFP language in common use, so all those things got conflated in a lot of people's minds. Now we have PureScript (which doesn't have laziness) and Elm (which doesn't have laziness or typeclasses). That said, you really should listen to @willtim about the `IO` type. Purity really is a big deal, and `IO` doesn't break it at all.
- runeks 9y ago> As soon as you have side-effects (an IO is a side-effect) you can through your assumptions about "strict conformation to definition" out of the window You misunderstand what an IO action is. An IO action in Haskell is a value which describes a side effect. For example, an IO Int is a value that describes a side effect which, at runtime will produce a value of type Int inside the IO monad. The difference is that the IO Int is a value, it’s a constant which describes how to perform something at runtime (also called promises in some languages). It’s like a callback function, which takes a value as an argument that will be available when it’s called (at runtime).
- dmitriid 9y agoRiight. The "Platonic ideal" again. "It's not the language it's the runtime!"
- deleted 9y ago[deleted]