Eh, IO String in Haskell is just as pure as String. Haskell only has a handful of escape hatches to break out of purity/referential transparency, like unsafePerformIO and unsafeInterleaveIO - but you don't need to (and shouldn't) use them at all. They're there for the runtime system to use and execute your code. See my other reply in this thread.
True. Thats why though Haskell is often considered the "most functional" out of others, but not Purely functional, because the type system allows for any side effects to be encapsulated within the context of a type.
They are if you ignore any resource limitations and thats the point really. A Turing machine is more of a mathematical model than a real world implementation as you cannot possibly express the notion of infinity in computer systems. There has to be an upper limit somewhere.
Instead of executing the side-effects (e.g. calling a function log that returns a string), you create objects that represent those actions (e.g. calling a function log that returns a IO<string>).
You compose these "objects that represent actions" with other objects (usually with map/flatMap).
Once you're done composing all your effects, you bubble them up to main and use an escape hatch to trigger the execution of all side-effects at once (sometimes called unsafePerformIO). In Haskell, you don't use the escape hatch at all - you bubble up all IO<A> actions to main, and the runtime will go through your tree of effects and execute them. This is when things actually get "impure" - but you don't care anymore because it's now beyond the boundary of your application.
Here's a sample implementation of what IO<A> would look like in scala: scalafiddle.io/sf/AnXRGhf/8 (should be fairly easy to read regardless of your background, let me know if it's not and you'd like to see this in another language)
You can't, so you hide it. In Elm's case, it's called Debug.log to emphasize that it's not something to be used commonly. Essentially it looks like the identity function (takes an argument and gives it back) except that it logs it to the console.
Just out of curiosity, how would you implement a pure function of
console.log
? I have no experience in functional languages.Answer: You cheat by accepting that there are side-effects in order to run the program.
See wiki.haskell.org/Introduction_to_IO
Eh,
IO String
in Haskell is just as pure asString
. Haskell only has a handful of escape hatches to break out of purity/referential transparency, likeunsafePerformIO
andunsafeInterleaveIO
- but you don't need to (and shouldn't) use them at all. They're there for the runtime system to use and execute your code. See my other reply in this thread.True. Thats why though Haskell is often considered the "most functional" out of others, but not Purely functional, because the type system allows for any side effects to be encapsulated within the context of a type.
That claim is as meaningful as the claim that no computer is Turing complete because they all have finite memory.
They are if you ignore any resource limitations and thats the point really. A Turing machine is more of a mathematical model than a real world implementation as you cannot possibly express the notion of infinity in computer systems. There has to be an upper limit somewhere.
Instead of executing the side-effects (e.g. calling a function
log
that returns astring
), you create objects that represent those actions (e.g. calling a functionlog
that returns aIO<string>
).You compose these "objects that represent actions" with other objects (usually with map/flatMap).
Once you're done composing all your effects, you bubble them up to
main
and use an escape hatch to trigger the execution of all side-effects at once (sometimes calledunsafePerformIO
). In Haskell, you don't use the escape hatch at all - you bubble up allIO<A>
actions tomain
, and the runtime will go through your tree of effects and execute them. This is when things actually get "impure" - but you don't care anymore because it's now beyond the boundary of your application.Here's a sample implementation of what
IO<A>
would look like in scala: scalafiddle.io/sf/AnXRGhf/8 (should be fairly easy to read regardless of your background, let me know if it's not and you'd like to see this in another language)You can't, so you hide it. In Elm's case, it's called
Debug.log
to emphasize that it's not something to be used commonly. Essentially it looks like the identity function (takes an argument and gives it back) except that it logs it to the console.More: package.elm-lang.org/packages/elm-...